2012-02-29 47 views
13

Đây là một truy vấn SQL Tôi muốn chuyển đổi để EF4.3Chuyển đổi một LEFT OUTER JOIN để Entity Framework

 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"); 

Dưới đây là LINQ tốt nhất mà tôi có thể đưa ra:

 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 
      }; 

tôi biết tôi cần phải kết hợp đầu tiên của tôi tham gia (giữa các ủy quyền & Authentications) vào, cho phép nói x và áp dụng DefaultIfEmpty nhưng không thể thực hiện cú pháp.

EDIT: hình ảnh để làm rõ: Data Model

Bất kỳ trợ giúp sẽ được đánh giá cao. Trân trọng.

Trả lời

33

Cú pháp cơ bản cho một "trái tham gia" trong LINQ là như thế này:

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 
}; 

Trong trường hợp của bạn, tôi là một chút nhầm lẫn vì các mối quan hệ thực thể bạn dường như được sử dụng trong LINQ don của bạn' t khớp với những cái được ngụ ý bởi SQL của bạn; là các mối quan hệ ở đây không-hoặc-một, không-hoặc-nhiều, một-một, vv? Cụ thể, bạn đang thực hiện việc này:

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

nhưng SQL của bạn ngụ ý rằng "Xác thực" là cha mẹ ở đây không có con "không được phép" nhiều hơn, không phải theo cách khác, sẽ giống như sau:

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

Nếu bạn có thể cho chúng ta biết rõ hơn về mô hình dữ liệu và những dữ liệu bạn mong đợi để thoát ra khỏi nó, chúng ta có thể dễ dàng giải thích cách thức truy vấn mà sẽ trông trong LINQ. Giả định rằng mối quan hệ của bạn phù hợp với những gì được gợi ý trong SQL, bạn sẽ có thể để có được những gì bạn muốn sử dụng các truy vấn LINQ sau:

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

Cảm ơn bạn đã biết chi tiết. Tôi đã đính kèm một hình ảnh trong câu hỏi của mình. Vui lòng xem nếu nó làm rõ tình hình của tôi. Cảm ơn vì đã trả lời. Nhiều đánh giá cao. – DoomerDGR8

+1

Với hình ảnh tôi nghĩ LINQ tôi đã đăng sẽ hoạt động. Nó sẽ cung cấp cho bạn mọi thứ từ bảng Xác thực, cộng với bất kỳ Ủy quyền phù hợp nào (nếu có) cho Xác thực này, cộng với bất kỳ Tổ chức phù hợp nào cho các Xác thực đó. –

+1

Một cập nhật nhỏ mà bạn có thể cần: như được viết, câu trả lời của tôi sẽ trả về Các ủy quyền không có bản ghi Tổ chức phù hợp - tham gia bên trái thứ hai thay vì tham gia bên trong. Tùy thuộc vào mô hình dữ liệu của bạn mà có thể hoặc không thể là một khả năng mà bạn cần phải lo lắng; nếu đó là một mối quan tâm cho tôi biết. –

-3

tôi đã đi trước và chuyển toàn bộ truy vấn đến một Stored Procedure trên cơ sở dữ liệu. Điều này giải quyết vấn đề bằng cách tránh LINQ và ObjectBuilder ở nơi đầu tiên.

+3

Dự phòng trường hợp xấu nhất rõ ràng, không phải là câu trả lời hữu ích. –

+0

Đối với tôi, đó là một trường hợp hiển nhiên khi sử dụng đúng công cụ cho công việc. – Vaiden

+2

Âm thanh giống như khi bạn cầm một cái búa, mọi thứ bạn thấy trông giống như móng tay. –

Các vấn đề liên quan