私は、SQL TableAdaptersからEntity Frameworkを使用してLinqに切り替えることを検討してきましたが、いくつかの要素が同時に私を怒らせてしまいました。Linq(Entity Framework)対動的データページングのSQL
私はASP.NET 4.0 C#VS2010プロジェクトサイトを持っています。
次のように私の要件は以下のとおりです。
- データはページング可能でなければならないデータは
- 動的(SelectedColumnName ASC/DESC BYすなわちORDER)発注可能でなければなりません
- データは、Webコントロール、テキストに基づいてフィルタリング可能でなければなりませんボックス、ドロップダウンなど。再び、動的に。
- 返された列は動的に構築可能でなければなりません
- 大きな表での作業はできるだけ敏感でなければなりません。ページングはこれに役立ちます。
- フロントエンドでレコード情報を表示する必要があります。 「100のレコード1〜20を表示」「5/20ページ」など
- プロジェクトは内部アクセス可能なサイトです。インターネットや何でもない。私の要件に基づいて
、私はSystem.Linq.Dynamicの名前空間を使用した動的LINQのを見て始めました。私はいくつかの成功を収めましたが、主に質問が過度に複雑になりました。
私の必要条件として、LinqとEntity Frameworkを標準SQLと比較して本当の理由はありますか?
私が知ることから、標準SQLは、私が理解し、制御できるクエリ言語で必要なすべてのコントロールを提供します。 Linqは私が驚くほど馴染みのない言語であり、私が必要とするようにすべての要素を動的にすることを許しません。
私はクエリにSQLストアドプロシージャ/テーブルアダプタを使用するのに間違っているでしょうか?
私がLinqの実験から学んだことの1つは、コードビハインドを介してプロパティを制御することによって情報の制御が大幅に向上することです。このデータを使用して、データを格納しているprocsを解析して、
これは、私が働いていた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は高速です)。
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ストアドプロシージャをテーブルアダプタ(これは私が今やっているものです)に格納しますが、コードビハインドからテーブルアダプタを呼び出して、データをmy gridviewsなどにデータバインドします。ページコードをかなりきれいに保ちながらテーブルアダプタ – HungryHippos