Linq枚举错误

时间:2016-02-03 02:02:28

标签: c# asp.net linq linq-to-entities

我从发布的表单数据中获取用户,但有时可能是空的。

var users = Request.Form.GetValues("users[]") == null ? null : Request.Form.GetValues("users[]").ToArray();

因此,如果为空,用户将变为null。但是,以下Linq查询不起作用。

 var submissions = db.QuickSearchViews.Where(x => (users != null && users.Contains(x.UserId)))
                                      .ToList();

错误:

  

其他信息:无法创建类型的null常量值   'System.String []'。仅实体类型,枚举类型或基元   在这种情况下支持类型。

2 个答案:

答案 0 :(得分:3)

我将假设这是基于错误消息的Entity Framework。此查询抛出错误消息的原因(您没有发布完整错误和堆栈跟踪,但它很可能是NotSupportedException)是双重的

  1. users不是您的上下文db(数据库映射)中的实体,并且检查它是否为null无法转换为SQL语句。

  2. users.Contains(x.userId)无法转换为SQL语句,因为用户不属于您的数据库。

  3. 您需要重新排序编写它的方式:

    var users = Request.Form.GetValues("users[]") == null ? null : Request.Form.GetValues("users[]").ToArray();
    if(users != null)
    {
         List<QuickSearchView> qsvs = db.QuickSeachViews.ToList();
         var submississions = qsvs.Where(x => users.Any(x.UserId));
    }
    else
    {
          //something when users is null
    }
    

    潜在地,这个也可以工作,但我没有测试过,我不记得了,因为我最近没有尝试过这样的事情:

    var submissions = db.QuickSearchViews.Where(x => users.Any(x.UserId));
    

    您可能需要首先调用类似db.QuickSearchViews.Load();的内容,但您需要对其进行测试。

    专业提示:

    如果您担心用户为空,则可以使用null coalescing operator ??。由于您提到空users为空时可以执行此操作:

    var users = (Request.Form.GetValues("users[]") ?? new string[0]).ToList();
    

    这将确保用户永远不会null,因此您无需检查它。但是,您甚至不需要在此帖子或原始帖子中调用ToList(),因为Request.Form.GetValues()会返回一个数组(string[]),该数组已经实现IEnumerable<T>以获取访问权限到linq扩展方法。

答案 1 :(得分:1)

用户不是模型的一部分,因此linq to entities正在尝试将其转换为sql,对于查询,它被翻译为常量,然后失败。考虑到比较用户== null正在sql中而不是在c#中进行评估,所以linq正在尝试编写整个句子。

我建议在没有用户的情况下分配空列表而不是null,并消除用户== null