实体框架:DbIsNullExpression的参数必须引用基元或引用类型

时间:2012-10-07 21:56:33

标签: c# sql-server entity-framework

我正在尝试使用实体来执行此操作:

    SELECT *
    FROM aspnet_Users u LEFT JOIN (SELECT u.UserId, p.Permission, p.MediaId, p.Valid
                         FROM aspnet_Users u LEFT JOIN Permission p ON u.UserId = p.UserId
                         WHERE p.MediaId = 57 AND p.Valid = 1
                         ) B 
                         ON u.UserId = B.UserId

这是C#代码:

    var up = from u in en.aspnet_Users
        join p in en.Permissions
         on u.UserId equals p.UserId into pu
        from p2 in pu.DefaultIfEmpty()
        where p2.MediaId == this.MediaId && p2.Valid == true
        select new
        {
         u.UserId,
         p2.PermissionId,
         p2.Permission1,
         p2.MediaId,
         p2.Valid
        };

    var ul = from us in en.aspnet_Users
       join pm in up
            on us.UserId equals pm.UserId into pm1
       from pm2 in pm1.DefaultIfEmpty()
       orderby us.LoweredUserName
       select new PermissionInfo { 
           Permission = (pm2 == null ? -1 : pm2.Permission1), 
           UserName = us.UserName, 
           UserId = us.UserId, 
           PermissionId = (pm2 == null ? -1 : pm2.PermissionId) };
    ret = ul.ToList();

然而,在最后一行得到了他的错误

DbIsNullExpression的参数必须引用基元或引用类型。

任何人都知道如何解决这个问题?感谢。

编辑回答1条建议:

    var up = from u in en.aspnet_Users
                     join p in en.Permissions
                         on u.UserId equals p.UserId into pu
                     from p2 in pu.DefaultIfEmpty()
                     where p2.MediaId == this.MediaId && p2.Valid == true
                     select new {u, p2};

            var ul = from us in en.aspnet_Users
                     join pm in up
                          on us.UserId equals pm.u.UserId into pm1
                     from pm2 in pm1.DefaultIfEmpty()
                     orderby us.LoweredUserName
                     select new PermissionInfo
                     {
                         Permission = (pm2 == null ? -1 : pm2.p2.Permission1),
                         UserName = us.UserName,
                         UserId = us.UserId,
                         PermissionId = (pm2 == null ? -1 : pm2.p2.PermissionId)
                     };

            ret = ul.ToList();

2 个答案:

答案 0 :(得分:2)

有一个类似的问题,我设法通过在sql之外移动空检查来解决它。在您的情况下,您可以在检查ToList()之前调用Null来执行此操作:

var intermediateUl = from us in en.aspnet_Users
    join pm in up
      on us.UserId equals pm.UserId into pmOuter
    from pm2 in pmOuter.DefaultIfEmpty()
    select new { us.UserName, us.UserId, pm2};

var ul = intermediateUl
    .ToList()
    .Select(o => new PermissionInfo { 
        Permission = (o.pm2 == null ? -1 : pm2.Permission1), 
        PermissionId = (o.pm2 == null ? -1 : pm2.PermissionId) 
        UserName = o.UserName, 
        UserId = o.UserId, 
     });

这个问题也让我感到惊讶,因为我上面的几行有一个类似的查询,外连接传递正常。似乎只有实体框架已知的实体才能使用linq外部构造检查null。任何其他类,无论匿名与否,都会混淆EF / linq。

我知道这个问题很老,但也许会帮助别人:)

答案 1 :(得分:0)

我意识到,因为在第二个查询中,它仍然具有与aspnet_Users表的左连接,它不需要在第一个查询中使用u,所以我将其更改为下面,它现在可以工作。但是,知道原始代码和建议代码失败的原因仍然很棒。

    var up = from u in en.aspnet_Users
                     join p in en.Permissions
                         on u.UserId equals p.UserId into pu
                     from p2 in pu.DefaultIfEmpty()
                     where p2.MediaId == this.MediaId && p2.Valid == true
                     select p2;

            var ul = from us in en.aspnet_Users
                     join pm in up
                          on us.UserId equals pm.UserId into pm1
                     from pm2 in pm1.DefaultIfEmpty()
                     orderby us.LoweredUserName
                     select new PermissionInfo
                     {
                         Permission = (pm2 == null ? -1 : pm2.Permission1),
                         UserName = us.UserName,
                         UserId = us.UserId,
                         PermissionId = (pm2 == null ? -1 : pm2.PermissionId)
                     };

            ret = ul.ToList();
相关问题