Linq 枚举错误

Linq Enumeration Error

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

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

所以,users如果为空则变为null。但是,以下 Linq 查询不起作用。

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

错误:

Additional information: Unable to create a null constant value of type 'System.String[]'. Only entity types, enumeration types or primitive types are supported in this context.

users 不是模型的一部分,因此 linq to entities 试图将其转换为 sql 并且对于查询,它被转换为常量,然后失败。考虑到比较 users==null 是在 sql 中评估的,而不是在 c# 中,所以 linq 试图写出整个句子。

我建议在没有用户时分配一个空列表而不是空列表并消除用户==null

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

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

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

您需要重新排序它的书写方式:

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,因此您不需要检查它。但是,你甚至不需要在这个或你原来的 post 中调用 ToList(),因为 Request.Form.GetValues() returns 一个数组(string[]),它已经实现了IEnumerable<T> 访问 linq 扩展方法。