使用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命令?
答案 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。