2012-02-29 77 views
13

這裏是一個SQL查詢我要轉換爲EF4.3轉換一個LEFT OUTER JOIN到實體框架

 command = database.GetSqlStringCommand(@" 
           select 
            H.AUTHENTICATION_ID, 
            USERNAME, 
            PERMISSIONS, 
            ORGANIZATION_IDENTIFIER, 
            O.ORGANIZATION_ID 
           from 
            AUTHENTICATION H 
             left join [AUTHORIZATION] T on H.AUTHENTICATION_ID=T.AUTHENTICATION_ID 
             join ORGANIZATION O on O.ORGANIZATION_ID = T.ORGANIZATION_ID 
           order by H.AUTHENTICATION_ID"); 

這裏是最好的LINQ我能想出:

 var query = from h in context.Authentications 
      join t in context.Authorizations on h.AuthenticationId equals t.Authentications.AuthenticationId 
      join o in context.Organizations on t.Organizations.OrganizationId equals o.OrganizationId 
      orderby 
      h.AuthenticationId 
      select new 
      { AUTHENTICATION_ID = (Int16?)h.AuthenticationId, 
       h.Username, 
       t.Permissions, 
       o.OrganizationIdentifier, 
       OrganizationID = (Int16?)o.OrganizationId 
      }; 

我知道我需要合併我的第一次加入(授權&身份驗證)到,讓我們說x和應用DefaultIfEmpty,但不能說出語法。

編輯:圖片澄清: Data Model

任何幫助將得到高度讚賞。問候。

回答

33

的基本語法「左連接」中的LINQ是這樣的:

from x in table1 
join y in table2 on x.id equals y.id into jointable 
from z in jointable.DefaultIfEmpty() 
select new 
{ 
    x.Field1, 
    x.Field2, 
    x.Field3, 
    Field4 = z == null ? 0 : z.Field4 
}; 

在你的情況,我有點困惑,因爲你似乎實體間關係被使用在你的LINQ別t匹配你的SQL隱含的那些;這裏的關係是零或一,零或多,一對一等?具體來說,你這樣做:

from h in context.Authentications 
join t in context.Authorizations on h.AuthenticationId equals t.Authentications.AuthenticationId 

但你的SQL意味着「認證」是父母在這裏與零或更多的「授權」的孩子,而不是其他方式,這會更喜歡:

from h in context.Authentications 
from t in h.Authorizations.DefaultIfEmpty() 

如果你可以給我們的數據模型的一個更好的主意,你希望擺脫它,我們可以更容易地解釋查詢會怎樣看Linq中的哪些數據。假設你的人際關係匹配的內容是由SQL暗示,你應該能得到你想要使用什麼以下LINQ查詢:

var query = from h in context.Authentications 
      from t in h.Authorizations.DefaultIfEmpty() 
      select new 
      { 
       h.AuthenticationId, 
       h.Username, 
       Permissions = t == null ? null : t.Permissions, 
       Organizations = t == null ? new EntitySet<Organization>() : t.Organizations 
      }; 

var query2 = from x in query 
      from o in x.organizations.DefaultIfEmpty() 
      select new 
      { 
       AUTHENTICATION_ID = (short?)x.AuthenticationId, 
       x.Username, 
       x.Permissions, 
       OrganizationIdentifier = o == null ? null : o.OrganizationIdentifier, 
       OrganizationID = o == null ? (short?)null : o.OrganizationID 
      }; 
+0

感謝您的詳細信息。我在我的問題中附上了一張圖片。請看看它是否澄清我的情況。感謝回覆。非常感激。 – DoomerDGR8 2012-03-01 05:50:40

+1

鑑於圖像,我認爲我發佈的LINQ將工作。它將爲您提供來自Authentications表的所有內容,以及此認證的任何匹配授權(如果有的話)以及任何與這些認證相匹配的組織。 – 2012-03-01 14:39:27

+1

您可能需要的一個小的更新:按照書面答案,我的答案將返回沒有匹配組織記錄的授權 - 第二個左連接而不是內連接。根據您的數據模型,可能或不可能您需要擔心;如果這是一個問題,請告訴我。 – 2012-03-01 14:46:42

-3

我繼續移動整個查詢到數據庫的存儲過程。這首先通過避免使用LINQ和ObjectBuilder解決了這個問題。

+3

明顯的最壞情況下的回退,不是一個有用的答案。 – 2016-02-24 18:09:54

+0

對我來說,使用正確的工具是一個明顯的例子。 – Vaiden 2016-04-14 13:13:26

+2

聽起來更像是當你拿着錘子時,你看到的所有東西看起來都像釘子一樣。 – 2016-04-14 15:04:46