2012-03-08 38 views
5

長時間潛伏者,第一次海報。過去我在這裏找到了一些很好的答案,所以我會來這裏看看我能否得到一點幫助!實體框架中的多次連接查詢

我是Linq的新手,我正在爲我的對象使用實體框架。我的項目中有一個.edmx文件。

首先我進口從VS 2010中附帶的示例頁面所使用System.Linq.Dynamic類,所以我可以添加到我的網頁這樣的:

使用System.Linq.Dynamic;

問題是,我不認爲我的連接工作正常。

這是我當前的代碼:

private void FetchData() 
{ 
    using (var Context = new ProjectEntities()) 
    { 
     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     // Alias names from Tables 
       { 
        u, 
        us 
       }) 
      .Join(Context.TechContacts,   // Table to Join 
       u => u.u.UserPrincipalName,  // Column to Join From 
       tc => tc.UPN,     // Column to Join To 
       (u, tc) => new     // Alias names from Tables 
       { 
        u = u, 
        tc = tc 
       }) 
       .Where(u => true) 
       .OrderBy("u.u.CompanyName") 
       .Select("New(u.u.CompanyName,tc.UPN,u.us.TotalItemSize)"); 

     // Add Extra Filters 
     if (!(string.IsNullOrWhiteSpace(SearchCompanyNameTextBox.Text))) 
     { 

      Query = Query.Where("u.CompanyName.Contains(@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?

SELECT u.Column1, 
u.Column2, 
us.Column1, 
tc.Column1 
FROM Users AS u 
INNER JOIN UserStats AS us 
ON u.msExchMailboxGuid = us.MailboxGuid 
INNER JOIN TechContacts AS tc 
ON u.UserPrincipalName = tc.UPN 

我需要保持動態。凡條款和。選擇字段名稱,你可以看到,現在的問題是,我需要做的uuCompanyName取回u.CompanyName場,因爲它是在我加入兩次。

我已經爲此搜索了一段時間,但沒有骰子呢。

任何幫助非常感謝!

編輯 - 這是我目前的查詢。它的工作原理,但它有點噩夢。

忍受着我。如果可以的話,我想包括所有的東西,即使它有點多。

動態列選擇對我來說是必須的。否則,我不妨堅持我的表適配器和存儲特效。能夠減少我的查詢返回更少的數據是我的目標之一。如果任何人都可以提出改進建議,我全都聽過?

我無法找到一種方法來停止必須選擇我的連接到子項中,當我加入SQL時,我只需要通過我的SELECT語句返回我想要的列。

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在後臺運行:

SELECT TOP (20) 
[Project1].[C1] AS [C1], 
[Project1].[objectGuid] AS [objectGuid], 
[Project1].[msExchMailboxGuid] AS [msExchMailboxGuid], 
[Project1].[CompanyName] AS [CompanyName], 
[Project1].[ResellerOU] AS [ResellerOU], 
[Project1].[DisplayName] AS [DisplayName], 
[Project1].[MBXServer] AS [MBXServer], 
[Project1].[MBXSG] AS [MBXSG], 
[Project1].[MBXDB] AS [MBXDB], 
[Project1].[MBXWarningLimit] AS [MBXWarningLimit], 
[Project1].[MBXSendLimit] AS [MBXSendLimit], 
[Project1].[MBXSendReceiveLimit] AS [MBXSendReceiveLimit], 
[Project1].[extensionAttribute10] AS [extensionAttribute10], 
[Project1].[legacyExchangeDN] AS [legacyExchangeDN], 
[Project1].[UserPrincipalName] AS [UserPrincipalName], 
[Project1].[Mail] AS [Mail], 
[Project1].[lastLogonTimestamp] AS [lastLogonTimestamp], 
[Project1].[createTimeStamp] AS [createTimeStamp], 
[Project1].[modifyTimeStamp] AS [modifyTimeStamp], 
[Project1].[altRecipient] AS [altRecipient], 
[Project1].[altRecipientBL] AS [altRecipientBL], 
[Project1].[DeletedDate] AS [DeletedDate] 
    FROM (SELECT [Project1].[objectGuid] AS [objectGuid], 
     [Project1].[msExchMailboxGuid] AS [msExchMailboxGuid], 
     [Project1].[CompanyName] AS [CompanyName], 
     [Project1].[ResellerOU] AS [ResellerOU], 
     [Project1].[DisplayName] AS [DisplayName], 
     [Project1].[MBXServer] AS [MBXServer], 
     [Project1].[MBXSG] AS [MBXSG], 
     [Project1].[MBXDB] AS [MBXDB], 
     [Project1].[MBXWarningLimit] AS [MBXWarningLimit], 
     [Project1].[MBXSendLimit] AS [MBXSendLimit], 
     [Project1].[MBXSendReceiveLimit] AS [MBXSendReceiveLimit], 
     [Project1].[extensionAttribute10] AS [extensionAttribute10], 
     [Project1].[legacyExchangeDN] AS [legacyExchangeDN], 
     [Project1].[UserPrincipalName] AS [UserPrincipalName], 
     [Project1].[Mail] AS [Mail], 
     [Project1].[lastLogonTimestamp] AS [lastLogonTimestamp], 
     [Project1].[createTimeStamp] AS [createTimeStamp], 
     [Project1].[modifyTimeStamp] AS [modifyTimeStamp], 
     [Project1].[altRecipient] AS [altRecipient], 
     [Project1].[altRecipientBL] AS [altRecipientBL], 
     [Project1].[DeletedDate] AS [DeletedDate], 
     [Project1].[C1] AS [C1], 
     row_number() OVER (ORDER BY [Project1].[CompanyName] ASC) AS [row_number] 
      FROM (SELECT 
       [Extent1].[objectGuid] AS [objectGuid], 
       [Extent1].[msExchMailboxGuid] AS [msExchMailboxGuid], 
       [Extent1].[CompanyName] AS [CompanyName], 
       [Extent1].[ResellerOU] AS [ResellerOU], 
       [Extent1].[DisplayName] AS [DisplayName], 
       [Extent1].[MBXServer] AS [MBXServer], 
       [Extent1].[MBXSG] AS [MBXSG], 
       [Extent1].[MBXDB] AS [MBXDB], 
       [Extent1].[MBXWarningLimit] AS [MBXWarningLimit], 
       [Extent1].[MBXSendLimit] AS [MBXSendLimit], 
       [Extent1].[MBXSendReceiveLimit] AS [MBXSendReceiveLimit], 
       [Extent1].[extensionAttribute10] AS [extensionAttribute10], 
       [Extent1].[legacyExchangeDN] AS [legacyExchangeDN], 
       [Extent1].[UserPrincipalName] AS [UserPrincipalName], 
       [Extent1].[Mail] AS [Mail], 
       [Extent1].[lastLogonTimestamp] AS [lastLogonTimestamp], 
       [Extent1].[createTimeStamp] AS [createTimeStamp], 
       [Extent1].[modifyTimeStamp] AS [modifyTimeStamp], 
       [Extent1].[altRecipient] AS [altRecipient], 
       [Extent1].[altRecipientBL] AS [altRecipientBL], 
       [Extent1].[DeletedDate] AS [DeletedDate], 
       1 AS [C1] 
       FROM [dbo].[Users] AS [Extent1] 
       INNER JOIN [dbo].[UserStats] AS [Extent2] ON [Extent1].[msExchMailboxGuid] = [Extent2].[MailboxGuid] 
       INNER JOIN [dbo].[TechContacts] AS [Extent3] ON [Extent1].[UserPrincipalName] = [Extent3].[UPN] 
      ) AS [Project1] 
    ) AS [Project1] 
WHERE [Project1].[row_number] > 120 
ORDER BY [Project1].[CompanyName] ASC 
+0

你說什麼意思,當你說*我不認爲我的加入運作良好*?它是否返回了正確的記錄?它慢嗎?你見過生成的SQL嗎? – Aducci 2012-03-08 17:39:09

+0

通常當我這樣加入時,我可以使用表的別名返回我想要的記錄。 f.ex如果我已經在我的SQL語句中調用了它,我可以使用u.Field1,u.Field2從Users表中撤消記錄,這些記錄已被別名爲u。如果我使用這樣的查詢,我必須使用u.u.FieldName將字段拉回來。這對我來說並不合適!看到我的.OrderBy聲明,看看我的意思。 – HungryHippos 2012-03-08 17:49:28

+0

如果它有效並且速度不慢,我不明白你在找什麼。似乎並沒有真正的問題 – Aducci 2012-03-08 17:58:39

回答

2

沒有太多的答案,但建議。首先,去搶LinqPad。在進行查詢優化時,它非常寶貴。其次,我敢打賭,由於使用.Join,你會得到一個巨大的查詢。 Linq2Entities有一個討厭的習慣,每次進行連接時都會創建投影(子查詢)。我會花一些質量時間與LinqPad和我的查詢,直到我得到我想要的查詢。

+0

謝謝,將有一個LinqPad玩,看看是什麼:) – HungryHippos 2012-03-08 18:42:15

+0

哦,這只是得到更多的樂趣。如果我可以用我目前擁有的功能更新我的OP。 – HungryHippos 2012-03-10 17:55:11

+0

好吧,我已經玩弄了LinqPad,但它對我來說並不是那麼容易,因爲沒有像自動完成這樣的很酷的功能,所以我不知道我打字的東西實際上是在工作。如果你在上面檢查我的OP,你會看到我目前正在運行的東西,但它明顯比我當前的TableAdapter和Stored Proc方法慢。 – HungryHippos 2012-03-10 18:09:49