如何选择与对象列表中的属性值共享属性值的所有对象

本文关键字:属性 对象 何选择 共享 列表 选择 | 更新日期: 2023-09-27 18:07:10

我有一个对象列表,我想重新加载它们的数据。像往常一样,我有几个选择。我只是想选择这些项目,但遇到了这个"附加信息":Unable to create a constant value of type 'Item'. Only primitive types or enumeration types are supported in this context.

// (System.Collections.Generic.List<Item> selectedItems)
System.Collections.Generic.List<Item> items;
var q = from i in db.Items
        where selectedItems.Any(s => s.Id == i.Id)
        select i;
items = q.ToList()

下面的结果与预期相同…

var q = db.Items.Where(i => selectedItems.Any(si => i.Id == si.Id));
items = q.ToList();

我可以重新连接每个对象并调用重新加载,但然后我将不得不(或不,但我不知道如何)在数据库中运行很多次来重新加载它们的Navigation Properties

到目前为止,我发现的唯一"好的"解决方案是选择selectedItemsId,然后像下面这样运行:

int[] itemIds = selectedItems.Select(i => i.Id).ToArray();
var q = db.Items.Where(i => itemIds.Any(iId => i.Id == iId)); //Of course `Contains` could be used instead of `Any` here, since `itemIds` is a simple array of integers
items = q.ToList();

但是,这是必要的还是有更直接,整洁或适当的方式来完成这一点?

如何选择与对象列表中的属性值共享属性值的所有对象

但是,这是必要的还是有更直接,整洁或适当的方式来完成这一点?

我想不起来。EF将尝试将您的where子句转换为SQL(这并不像您想象的那么容易)。当它解析表达式并遇到对非基本类型集合的Any的调用时,它不知道如何将该列表一般地转换为要放入in子句中的值列表,并给出您引用的错误。

当源集合是原始类型或枚举类型的集合时,它可以将源集合转换为值列表并创建in子句。Contains做同样的事情(它也更短,更接近意图IMHO):

var q = db.Items.Where(i => itemIds.Contains(i.Id)); 
相关文章: