左外连接linq查询对象引用未设置为对象的实例

时间:2015-03-04 10:21:39

标签: c# linq linq-to-entities

我有三个表,我在两个表上执行内连接,而不是左外连接 为什么以下查询返回给我这个错误   " linq查询对象引用未设置为对象的实例"

  var model = from p in Uow.Instance.RepoOf<RoleMenuMetrix>().GetAll()
            from n in Uow.Instance.RepoOf<NavigationMenu>().GetAll().Where(q => q.Id == p.MenuId)
            from m in
                Uow.Instance.RepoOf<NavigationButton>()
                    .GetAll()
                    .Where(q => q.NavigationMenuId == n.Id)
                    .DefaultIfEmpty()
            where p.RoleId == Guid.Parse("96246E99-6BF2-4A3D-8D2C-263DDEF2F97B")
                  && n.IsActive && n.ApplicationName == "MEM"
            select new
            {
                p.MenuId,
                p.RoleId,
                n.Name,
                n.ParentId,
                ButtonName = m.ButtonName == null ? "" : m.ButtonName // when i comment this it works fine
            };

linqPad中的以下查询工作正常

from p in P_RoleMenuMetrixes
from n in NavigationMenus.Where(q => q.Id == p.MenuId)
from m in NavigationButtons.Where(q => q.NavigationMenuId == n.Id).DefaultIfEmpty()
where p.RoleId == Guid.Parse("96246E99-6BF2-4A3D-8D2C-263DDEF2F97B")
&& n.IsActive && n.ApplicationName == "MEM"
select new
{
    p.MenuId,
    p.RoleId,
    n.Name,
    n.ParentId,
    m.ButtonName
}

错误截图

enter image description here

3 个答案:

答案 0 :(得分:3)

当您使用DefaultIfEmpty时,如果未找到匹配项,则会分配默认值,因此您需要检查null并指定正确的值,如下所示: -

ButtonName = m!= null ? m.ButtonName  : String.Empty

我在考虑ButtonNamestring,如果不是,您可以相应地更改查询。

答案 1 :(得分:0)

您需要检查空值,使用以下代码

   ButtonName = m== null ?   "": m.ButtonName

答案 2 :(得分:0)

错误揭示了代码中存在更严重的缺陷。 LINQ语句不会转换为一个SQL语句(如在Linqpad中执行的LINQ),而是三个单独的语句,其结果在内存中连接。所以它只是对象的LINQ。因此空引用。

您的UoW / Repo架构需要重大修改!您已禁用LINQ语句的可组合性。 GetAll()不应返回List<T>(如屏幕截图所示),IQueryable<T>,即DbSet

目前,GetAll()将始终将整个表提取到内存中。之后进行的任何过滤都不会影响SQL语句。