C# 错误:LINQ表达式节点类型';阵列索引';在LINQ to实体中不支持

C# 错误:LINQ表达式节点类型';阵列索引';在LINQ to实体中不支持,c#,asp.net-mvc,entity-framework,linq,C#,Asp.net Mvc,Entity Framework,Linq,正在开发MVC5应用程序。我有一个字符串数组定义为 string[] myArray; 它有三个项目 {string[3]} [0]: "a411d1bc-21f7-4e4d-a4d3-4dd36e1b319f" [1]: "ef4e3655-fa6f-4dfc-b2d4-178ac5914f0b" [2]: "d75a98c5-a829-43c5-b2cf-d50be1189a05" 这些实际上是AspNetUser表中记录的主键。我想使用多个“WHERE”中的数组项执行

正在开发MVC5应用程序。我有一个字符串数组定义为

string[] myArray;
它有三个项目

{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());
    }
}
IQueryable事件=db.events;
if(myArray!=null)
{
事件=事件。包括(a=>a.AspNetUser);
for(int i=0;i u.AspNetUser.Id==myArray[i].ToString());
}
}
因此,正如您所看到的,我基本上是在数组(包含所有PK)中循环,并在WHERE子句中使用它

但是,就在我击中第一条线的时候。在循环中的哪一行我得到了这个错误:

LINQ to实体中不支持LINQ表达式节点类型“ArrayIndex”

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


最后,对于我所描述的动态场景,在正常情况下,当在EntityFramework中执行类似于
where
的操作时,如何使用OR语句而不是where的AND命令?
,它实际上不会像在可枚举(如列表)上操作时那样在内存中执行。相反,它转换为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);
}

问题是,您试图在LINQtoSQL表达式中访问数组,但无法识别该数组。您只需拉出
myArray[i]
并将其设置为一个变量,然后使用该变量:

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

基本上,
。其中,
将您拥有的内容转换为SQL查询,但它不知道如何将
myArray[i]
转换为SQL。

如果您需要相同的顺序,则可以执行以下操作:

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));
}

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

谢谢@stybl。当我循环时,我如何做类似于OR子句(contains/in)的操作,而不是一堆AND?@WebDevGuy2您必须进一步解释一下您的意思。你只想要一个匹配项吗?我想你是用上面的包含行回答的。谢谢谢谢但是,这不是myArray包含xyz的搜索吗?我想在AspNetUser表中搜索Id包含myArray中元素的位置。是的,它正在整个AspNetUser表中搜索myArray数组中包含的用户。因此,如果您的用户表中有ID A、B、C、D和E,myArray有B、C和D,那么结果将是ID为B、C或D的用户(三个用户)。此外,如果您包含AspNetUser的唯一原因是进行筛选(您实际上不想要或不需要AspNetUser表中的数据),那么您可以完全跳过.Include。EF仍然会正确过滤并只返回匹配的记录,而且会更快。谢谢@RobertMcKee。我在aspnetuser表中有一个用户名、firstname和lastname字段,所以我想引用这些字段。所以这个案子我需要它。谢谢!:)因为它只返回一条记录,而不是全部3条。
IQueryable<Event> events = db.Events;

if (myArray != null)
{
    events = events
      .Include(a => a.AspNetUser)
      .Where(a=> myArray.Contains(a.AspNetUser.Id));
}
var myGuidArray = myArray
  .Select(a=> Guid.Parse(a))
  .ToArray();