C# 两个看似相同的LINQ查询。一个有效,另一个无效';T

C# 两个看似相同的LINQ查询。一个有效,另一个无效';T,c#,asp.net-mvc,linq,C#,Asp.net Mvc,Linq,以下查询有效: 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))

以下查询有效:

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上产生一个空引用错误


我做错了什么?如何使第二个结果生效?

您的第一个查询由查询提供程序解释,以生成相应的查询以返回请求的结果。对于查询提供程序,构造
join。。。从x中的y进入x。DefaultIfEmpty()
是生成左外部联接的符号。当实体具体化时,提供者识别
NULL
值以及给定类型的相应默认值。这些默认值是在计算涉及它们的表达式时使用的

但是,当您将所有结果拉入列表时,第二个查询将拉入LINQ to对象。现在查询这些列表需要遵守常规的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();

工作得很好。非常感谢你!
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();