我一直在尋找使用實體框架從SQL TableAdapters切換到Linq,但是有些元素阻止了我,同時也讓我發瘋。Linq(實體框架)與SQL的動態數據分頁
我有一個ASP.NET 4.0 C#VS2010項目網站。
我的要求如下:
- 數據必須分頁
- 數據必須訂購動態(即ORDER BY SelectedColumnName ASC/DESC)
- 數據必須基於web控件是過濾,文本盒子,下降等。再次,動態。
- 返回的列必須是可動態構建的
- 使用大型表必須儘可能地做出響應。尋呼有助於此。
- 必須顯示前端記錄信息。即「顯示記錄1-20 of 100」「第5頁,共20頁」等。
- 項目僅限內部訪問站點。不在互聯網上或任何東西。
根據我的要求,我開始在動態的LINQ看使用System.Linq.Dynamic命名空間。我取得了一些成功,但主要是我的疑問變得過於複雜。
對於我的要求,是否有任何真正的理由使用Linq和實體框架與標準SQL?
從我所知道的情況來看,標準SQL爲我提供了所需的所有控件,並使用了我能理解和控制的查詢語言。 Linq是一種我不太熟悉的語言,並且不允許我像所需要的那樣使所有元素動態變化。
我會錯誤地回去使用SQL存儲過程/表適配器進行查詢嗎?
我從Linq的實驗中學到的一件事是,通過代碼隱藏控制屬性可以更好地控制信息,所以我可以使用這些數據來解析存儲的數據饋送到GridView的數據。
這是我正在同一個LINQ表達式的例子:
private void FetchData()
{
using (var Context = new ProjectEntities())
{
string Fields = GetDynamicFields();
var Query =
Context.Users
.Join(Context.UserStats, // Table to Join
u => u.msExchMailboxGuid, // Column to Join From
us => us.MailboxGuid, // Column to Join To
(u, us) => new // Declare Columns for the next Join
{
ObjectGuid = u.objectGuid,
msExchMailboxGuid = u.msExchMailboxGuid,
CompanyName = u.CompanyName,
ResellerOU = u.ResellerOU,
DisplayName = u.DisplayName,
MBXServer = u.MBXServer,
MBXSG = u.MBXSG,
MBXDB = u.MBXDB,
MBXWarningLimit = u.MBXWarningLimit,
MBXSendLimit = u.MBXSendLimit,
MBXSendReceiveLimit = u.MBXSendReceiveLimit,
extensionAttribute10 = u.extensionAttribute10,
legacyExchangeDN = u.legacyExchangeDN,
UserPrincipalName = u.UserPrincipalName,
Mail = u.Mail,
lastLogonTimeStamp = u.lastLogonTimestamp,
createTimeStamp = u.createTimeStamp,
modifyTimeStamp = u.modifyTimeStamp,
altRecipient = u.altRecipient,
altRecipientBL = u.altRecipientBL,
DeletedDate = u.DeletedDate,
MailboxGuid = us.MailboxGuid,
Date = us.Date,
AssociatedItemCount = us.AssociatedItemCount,
DeletedItemCount = us.DeletedItemCount,
ItemCount = us.ItemCount,
LastLoggedOnUserAccount = us.LastLoggedOnUserAccount,
LastLogonTime = us.LastLogonTime,
StorageLimitStatus = us.StorageLimitStatus,
TotalDeletedItemSize = us.TotalDeletedItemSize,
TotalItemSize = us.TotalItemSize,
MailboxDatabase = us.MailboxDatabase
})
.Join(Context.TechContacts, // Table to Join
u => u.UserPrincipalName, // Column to Join From
tc => tc.UPN, // Column to Join To
(u, tc) => new // Declare Final Column Names
{
ObjectGuid = u.ObjectGuid,
msExchMailboxGuid = u.msExchMailboxGuid,
CompanyName = u.CompanyName,
ResellerOU = u.ResellerOU,
DisplayName = u.DisplayName,
MBXServer = u.MBXServer,
MBXSG = u.MBXSG,
MBXDB = u.MBXDB,
MBXWarningLimit = u.MBXWarningLimit,
MBXSendLimit = u.MBXSendLimit,
MBXSendReceiveLimit = u.MBXSendReceiveLimit,
extensionAttribute10 = u.extensionAttribute10,
legacyExchangeDN = u.legacyExchangeDN,
UserPrincipalName = u.UserPrincipalName,
Mail = u.Mail,
lastLogonTimeStamp = u.lastLogonTimeStamp,
createTimeStamp = u.createTimeStamp,
modifyTimeStamp = u.modifyTimeStamp,
altRecipient = u.altRecipient,
altRecipientBL = u.altRecipientBL,
DeletedDate = u.DeletedDate,
MailboxGuid = u.MailboxGuid,
Date = u.Date,
AssociatedItemCount = u.AssociatedItemCount,
DeletedItemCount = u.DeletedItemCount,
ItemCount = u.ItemCount,
LastLoggedOnUserAccount = u.LastLoggedOnUserAccount,
LastLogonTime = u.LastLogonTime,
StorageLimitStatus = u.StorageLimitStatus,
TotalDeletedItemSize = u.TotalDeletedItemSize,
TotalItemSize = u.TotalItemSize,
MailboxDatabase = u.MailboxDatabase,
// New Columns from this join
UPN = tc.UPN,
Customer_TechContact = tc.Customer_TechContact,
Customer_TechContactEmail = tc.Customer_TechContactEmail,
Reseller_TechContact = tc.Reseller_TechContact,
Reseller_TechContactEmail = tc.Reseller_TechContact,
Reseller_Name = tc.Reseller_Name
})
.Where(u => true)
.OrderBy(GlobalVars.SortColumn + " " + GlobalVars.SortDirection)
.Select("New(" + Fields + ")");
// Add Extra Filters
if (!(string.IsNullOrWhiteSpace(SearchCompanyNameTextBox.Text)))
{
Query = Query.Where("CompanyName.StartsWith(@0)", SearchCompanyNameTextBox.Text);
}
// Set the Record Count
GlobalVars.TotalRecords = Query.Count();
// Add Paging
Query = Query
.Skip(GlobalVars.Skip)
.Take(GlobalVars.Take);
// GridView Datasource Binding
GridViewMailboxes.DataSource = Query;
GridViewMailboxes.DataBind();
}
}
這是通過一個SQL查詢同樣的事情爲例:
DECLARE @SQLSTATEMENT NVARCHAR(4000);
DECLARE @FieldList varchar(MAX);
DECLARE @OrderBy varchar(100);
DECLARE @OrderDirection varchar(100);
DECLARE @PageSize int;
DECLARE @StartRow int;
SET @FieldList = 'u.UserPrincipalName, u.Mail, us.TotalItemsize, tc.UPN';
SET @OrderBy = 'u.CompanyName';
SET @OrderDirection = 'ASC';
SET @PageSize = 20;
SET @StartRow = 80;
SET @SQLSTATEMENT = '
SELECT TOP(@PageSize) * FROM
(
SELECT ' + @FieldList + '
,row_number() OVER (ORDER BY @OrderBy ' + @OrderDirection + ') AS [row_number]
FROM Users As u
INNER JOIN UserStats as us
ON u.msExchMailboxGuid = us.MailboxGuid
INNER JOIN TechContacts AS tc
ON tc.UPN = u.UserPrincipalName
) AS r
WHERE r.[row_number] > @StartRow '
EXEC sp_executesql @SQLSTATEMENT,
N'@FieldList varchar(MAX), @OrderBy varchar(100), @OrderDirection varchar(100), @PageSize int, @StartRow int',
@FieldList, @OrderBy, @OrderDirection, @PageSize, @StartRow
我明白這是怎麼樣的一個懸而未決的問題,如果我能更清楚地說明,我當然會。然而,我在考慮我的要求的情況下努力看到使用Linq的好處。 Linq在編寫完全動態的查詢方面似乎不太好,並且大概必須在任何地方執行SQL(因此SQL更快?)。
我建立的一個解析所有我需要到globalvars,我就可以使用調用數據前端控制:
public class GlobalVars
{
public static int TotalRecords = 0;
public static int TotalPages = 0;
public static int CurrentPage = 0;
public static int LowerPage = 0;
public static int UpperPage = 0;
public static int Take = 0;
public static int Skip = 0;
public static string SortColumn = "CompanyName";
public static string SortDirection = "Ascending";
}
謝謝,就是我在找什麼。我可能會將我的SQL存儲過程存儲在表適配器中(這正是我現在所做的),但是從代碼隱藏中調用表適配器,然後將結果數據綁定到我的網格視圖中。這將使我最終控制關於發送給表適配器,同時保持頁面代碼相當乾淨:) – HungryHippos 2012-03-11 14:18:36