这是我想要转换为 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 但无法弄清楚语法。
编辑:用于澄清的图像:
任何帮助将不胜感激。问候。
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
};
鉴于问题图中存在外键,这样的事情怎么样?
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
};
不过,也可能是小写字母的后备
我经常发现 EF 总体上效果很好。然而,有时解决此类问题的最佳方法是在 SQL 中创建一个将所有这些 JOIN 包装在一起的 VIEW。然后使用 EF 从 VIEW 返回结果。
我继续将整个查询移至数据库上的存储过程。这首先通过避免使用 LINQ 和 ObjectBuilder 来解决问题。