错误:LINQ表达式节点类型' ArrayIndex' LINQ to Entities不支持

时间:2017-08-14 19:13:59

标签: c# asp.net-mvc entity-framework linq

使用MVC5应用程序。我有一个字符串数组定义为....

string[] myArray;

它有3个项目......

{string[3]}
   [0]: "a411d1bc-21f7-4e4d-a4d3-4dd36e1b319f"
   [1]: "ef4e3655-fa6f-4dfc-b2d4-178ac5914f0b"
   [2]: "d75a98c5-a829-43c5-b2cf-d50be1189a05"

这些实际上是AspNetUser表中记录的主键。我想使用多个" WHERE"中的数组项执行EF WHERE子句。 (所以基本上我想从AspNetUser表中检索这3个用户。)到目前为止,这是我的代码...

IQueryable<Event> events = db.Events;

if (myArray != null)
{
    events = events.Include(a => a.AspNetUser);

    for(int i = 0; i <= myArray.Length-1; i++)
    {
        events = events.Where(u => u.AspNetUser.Id == myArray[i].ToString());
    }
}

因此,正如您所看到的,我基本上通过数组(包含所有PK)循环并在我的WHERE子句中使用它。

但是,当我在循环中点击第一个.WHERE行时,我收到此错误:

  

LINQ表达式节点类型&#39; ArrayIndex&#39; LINQ to Entities不支持。

我在这里做错了什么?有更好的方法吗?

最后,对于我所描述的动态场景,如何使用OR语句而不是AND命令?

3 个答案:

答案 0 :(得分:4)

在正常情况下,当在EntityFramework中执行类似Where的操作时,它实际上并没有在内存中执行,就像操作可枚举(如List)一样。相反,它转换为SQL,然后由Db提供程序执行。这意味着执行某些操作,例如在对象上使用扩展方法,或者在您的情况下,通过索引从数组中获取元素不是一种选择,因为转换器无法将这些内容转换为SQL。

要修复现有代码,您需要像这样修改for循环:

for(int i = 0; i <= myArray.Length-1; i++)
{
    var temp = myArray[i].ToString();
    events = events.Where(u => u.AspNetUser.Id == temp);
}

将数组操作移到查询之外允许EntityFramework将其正确转换为SQL。

更好的方法来做你想做的事情如下:

var result = events.Where(u => myArray.Contains(u.AspNetUser.Id));

答案 1 :(得分:2)

如果您以相同的顺序需要它们,那么您可以这样做:

IQueryable<Event> events = db.Events;

if (myArray != null)
{
    events = events
      .Include(a => a.AspNetUser)
      .Where(a=> myArray.Contains(a.AspNetUser.Id))
      .ToList()
      .OrderBy(a=>myArray.IndexOf(a.AspNetUser.Id));
}

如果您不在乎他们是否在同一个订单中,那么您可以这样做:

IQueryable<Event> events = db.Events;

if (myArray != null)
{
    events = events
      .Include(a => a.AspNetUser)
      .Where(a=> myArray.Contains(a.AspNetUser.Id));
}

如果Id是guid(您可能不是),您可能需要将字符串数组转换为guid数组。如果是这样,那就这样做:

var myGuidArray = myArray
  .Select(a=> Guid.Parse(a))
  .ToArray();

然后将上述查询更改为引用myGuidArray而不是myArray。

答案 2 :(得分:1)

问题是您尝试在Linq to SQL表达式中访问您的数组并且无法识别它。您只需要提取myArray[i]并将其设置为变量,然后使用变量:

var myVariable = myArray[i].ToString();
events = events.Where(u => u.AspNetUser.Id == myVariable);

基本上.Where正在使用你所拥有的并试图将其变成SQL查询,但它不知道如何将myArray[i]转换为SQL。