我在堆栈上看到了一些相关的问题,但不知道如何解决我的问题,因为我做了三个表左外连接。 RoleUser
和Role
是实体对象
var query = from u in Context.Users
join ru in Context.RoleUsers on u.Id equals ru.UserId into plv
from x in plv.DefaultIfEmpty(new RoleUser())
join r in Context.Roles on x.RoleId equals r.Id into pii
from y in pii.DefaultIfEmpty(new Role())
orderby u.Id, y.Id
select new UserWithRole() { Id = u.Id, User = u, Role = y };
答案 0 :(得分:1)
由于错误解释了您无法在linq查询中创建,因此他们映射了类型(RoleUser
和Role
)。而是使用DefaultIfEmpty()
。以下内容:
var roles = from ru in Context.RoleUsers
join r in Context.Roles on ru.RoleId equals r.Id
select new { ru.UserId, role = r };
var query = from u in Context.Users
join r in roles on u.Id equals r.UserId into plv
from x in plv.DefaultIfEmpty()
select new UserWithRole() { Id = u.Id, User = u, Role = x.role };
但是,我建议查看导航属性 - 这样您就不必构建连接并使用它,就好像它是正常的"对象。
答案 1 :(得分:1)
问题是DefaultIfEmpty(new RoleUser())
和DefaultIfEmpty(new Role())
调用,因为EF无法将常量实体对象的创建转换为SQL。
因此,您需要使用DefaultIfEmpty()
的无参数重载,并在具体化查询结果中处理null
个对象。
如果您不需要IQueryable<T>
结果,可以使用中间匿名类型投影,使用AsEnumerable()
进行LINQ to Objects上下文并进行最终所需投影:
var query = (from u in Context.Users
join ru in Context.RoleUsers on u.Id equals ru.UserId into userRoles
from ru in userRoles.DefaultIfEmpty()
join r in Context.Roles on ru.RoleId equals r.Id into roles
from r in roles.DefaultIfEmpty()
orderby u.Id, r.Id
select new { User = u, Role = r }
)
.AsEnumerable() // db query ends here
.Select(x => new UserWithRole
{
Id = x.User.Id,
User = x.User,
Role = x.Role ?? new Role() // now this is supported
});