21

这是我要转换为 EF4.3 的 SQL 查询

        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 但无法弄清楚语法。

编辑:图片澄清: 数据模型

任何帮助将不胜感激。问候。

4

3 回答 3

50

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 中使用的实体关系与您的 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 
             };
于 2012-02-29T20:40:32.793 回答
0

鉴于问题图中存在的外键,这样的事情怎么样?

var query = from a in context.Authentications
            select new
            {
                a.AuthenticationID,
                a.Username,
                a.Authorisations.Permissions ?? false,
                a.Authorisations.Organisations.OrganisationIdentifier ?? 0
                a.Authorisations.Organisations.OrganisationID ?? 0
            };
于 2018-11-30T11:22:25.167 回答
-7

我继续将整个查询移动到数据库上的存储过程。这首先通过避免使用 LINQ 和 ObjectBuilder 来解决问题。

于 2014-02-14T19:09:43.723 回答