以下查询有效:
var result = (from p in db.Permissions
join z in db.PermissionOverridesByUsers on p.id equals z.PermissionID into x
from y in x.DefaultIfEmpty()
where userRoleIds.Contains((Guid)(p.ParentRoleID))
select new RolePermissionViewModel
{
id = p.id,
Name = p.Name,
IsSet = ((y.id != null && y.id > 0) ? false : true)
}).ToList(); // If an exception exists, IsSet = false, otherwise = true.
这个在 IsSet
上产生空引用错误var query1 = (from p in db.Permissions
where userRoleIds.Contains((Guid)(p.ParentRoleID))
select p).ToList();
var query2 = (from ov in db.PermissionOverridesByUsers
where ov.AffectedUserID == id
select ov).ToList();
var result = (from q1 in query1
join z in query2 on q1.id equals z.PermissionID into x
from y in x.DefaultIfEmpty()
select new RolePermissionViewModel
{
id = q1.id,
Name = q1.Name,
IsSet = ((y.id != null && y.id > 0) ? false : true)
}).ToList();
我做错了什么?如何使第二个结果工作?
答案 0 :(得分:1)
查询提供程序会解释您的第一个查询,以生成相应的查询以返回请求的结果。对于查询提供程序,构造join ... into x from y in x.DefaultIfEmpty()
是生成左外连接的标志。随着实体的具体化,提供者识别NULL
值以及给定类型的相应默认值。这些默认值是在评估涉及它们的表达式时使用的。
当您将所有结果拉入列表时,您的第二个查询将被拉入LINQ to Objects。现在查询这些列表受到常规C#规则的约束。现在x.DefaultIfEmpty()
部分现在将生成一个项目的集合,该项目是集合类型的默认值。在引用类型的情况下,这意味着null
。您需要提供替代(非空)值才能使用。默认实例通常就足够了。
var result =
(from q1 in query1
join z in query2 on q1.id equals z.PermissionID into x
from y in x.DefaultIfEmpty(new PermissionOverridesByUsers())
select new RolePermissionViewModel
{
id = q1.id,
Name = q1.Name,
IsSet = ((y.id != null && y.id > 0) ? false : true)
}).ToList();