2012-03-11 12 views
1

私は、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"; 
    } 

答えて

3

使用してストアドプロシージャは常に速くなります。

私は、データを呼び出すために使用することができますglobalvarsに私が必要とするすべてを解析し、フロントエンドのコントロールを構築しました。

さらに、Linqではなく、SQLコードで何が起こっているのかを実際に理解するのがはるかに簡単です。

実際にあなたのコードからSQL文でそれを呼び出すことを意味しますか? それでも読みやすくなります。そして、終わりには、彼らは同じことを生み出します。

Linqは、取得済みのすべてのリストを照会するのに適しています。

たとえば、リストがありますが、WHERE x = yと一致するオブジェクトと新しいリストWHERE x = zが必要です。データベースを再クエリーせずにこれを行うことができます。

データベースに行く場合は、sqlクエリを使用しても問題ありません。これは、リストをさらに操作するために必要であれば、LINQによって使用されます。

一部の人は反対するかもしれませんが、そのすべてが下手です。私は個人的にSQLコードステートメントを使用してそれらを呼び出します。

+0

ありがとう、ちょうど私が探していたもの。私はおそらく私のSQLストアドプロシージャをテーブルアダプタ(これは私が今やっているものです)に格納しますが、コードビハインドからテーブルアダプタを呼び出して、データをmy gridviewsなどにデータバインドします。ページコードをかなりきれいに保ちながらテーブルアダプタ – HungryHippos

関連する問題