首页 > 解决方案 > 如何编写返回包含子数组的对象的 EF Core 外连接?

问题描述

我正在尝试在 Linq to Sql 中进行左外连接,以便包含给定用户的所有角色:

from au
    in Db.AspNetApplicationUsers
where au.ApplicationId == applicationId
join u in Db.AspNetUsers 
    on au.UserId equals u.Id
join r in Db.AspNetUserRoles 
    on au.UserId equals r.UserId 
    into ur
from userRole in ur.DefaultIfEmpty()
select new UserSummary
{
    Active = au.Active,
    Email = u.NormalizedEmail,
    Name = u.FullName,
    Id = u.Id,
    LastLogin = u.LastLogin,
    LastPasswordChange = u.PasswordLastChanged,
    LockedOut = u.LockoutEnabled,
    Roles = (from x in ur where userRole.RoleId != null select userRole.RoleId).ToArray()
}

但收到以下错误:

System.InvalidOperationException: 'When called from 'VisitLambda', rewriting a node of type 'System.Linq.Expressions.ParameterExpression' must return a non-null value of the same type. Alternatively, override 'VisitLambda' and change it to not visit children of this type.'

我不经常在 EF 中使用外连接,所以我确定我只是弄乱了语法。

是否可以将数组返回到 Linq to SQL 中的属性?

如果我在代码不再失败where userRole.RoleId != null之后添加条件,但在序列化期间会失败。from userRole in ur.DefaultIfEmpty()我已经禁用了延迟加载,所以这很有趣。

标签: c#entity-framework-corelinq-to-entitiesef-core-3.1

解决方案


根据 CamiloTerevinto 的建议,以下工作正常:

from au
    in Db.AspNetApplicationUsers
where au.ApplicationId == applicationId
select new UserSummary
{
    Active = au.Active,
    Email = au.User.NormalizedEmail,
    Name = au.User.FullName,
    Id = au.User.Id,
    LastLogin = au.User.LastLogin,
    LastPasswordChange = au.User.PasswordLastChanged,
    LockedOut = au.User.LockoutEnabled,
    Roles = au.User.AspNetUserRoles.Where(r => r.RoleId != null).Select(r => r.RoleId).ToArray()
}

推荐阅读