使用 LINQ Where 与查找从业务对象列表中检索给定业务对象的正确方法是什么

本文关键字:业务 对象 是什么 方法 检索 列表 Where LINQ 查找 使用 | 更新日期: 2023-09-27 18:35:25

假设我有以下项目列表:

List<Item> items = Item.GetSomeItems();

我想从项目列表中检索一个带有 id 的特定项目:

int itemID = 2;

以下哪种方式是检索项目的正确和正确方法?

Item item = items.Find(x => x.ItemID == itemID);

Item item items.Where(x => x.ItemID == itemID).FirstOrDefault();

也许这些都不是使用 LINQ 的最佳解决方案。 无论哪种方式,对最佳方法的解释都会有所帮助,因为我经常检索单个业务对象项。何时使用哪个功能也很棒。谢谢。

使用 LINQ Where 与查找从业务对象列表中检索给定业务对象的正确方法是什么

我不知道

Find()Where()之间的实现差异是什么。虽然我怀疑它们很巧合,但我建议坚持使用 LINQ 扩展方法(Where()Single[OrDefault]()等),而不是特定于所选集合实现的方法。因为它们是IEnumerable<T>上的扩展方法,所以如果需要,你可以更灵活地选择不同的集合实现。

对于奖励积分:

不过,这里有几件事让我担心 - 您从某个地方加载内容,然后将它们过滤到内存中。我更愿意看到更类似于以下内容的内容:

Item item = Item.GetItemForId(2);

这将过滤留给(大概)数据库。虽然这可能违反了SRP,所以实际上你正在走向:

IRepository<Item> repository = this.itemRepository;
Item item = repository.Get(2);

如果您使用的是完整的 Linq to SQL/Entities,则可以使用延迟执行并执行以下操作:

Item item = context.Items.SingleOrDefault(i => i.Id == 2);

这不会在调用 SingleOrDefault() 之前加载所有项目,而是查看 who 表达式并为其生成适当的 SQL,如下所示:

SELECT [fields] FROM Item WHERE Id = @id

这都是我的假设,但我确实想明确指出,Linq to Entities(实体框架)和 Linq to SQL(构建要发送到数据库的 SQL 语句)与 Linq to Objects 之间存在很大差异,后者是相同的方法调用,但处理内存中的集合对象。

你应该使用类似以下内容的内容:

Item item = items.FirstOrDefault(x => x.ItemID == itemID);

根据您希望它的工作方式,在"单个"、"单个或默认"、"第一个"和"第一个或默认"之间选择作为要使用的 LINQ 方法。 如果列表中的多个项目与查询匹配,则 Single 将引发错误,First 将仅返回它遇到的第一个与查询匹配的项目。 如果没有 OrDefault,如果没有找到匹配项,它们将抛出错误,在这种情况下它将返回 null。 这比尝试使用 null 并获取 null 引用异常要好。

因此,例如,如果您只想处理只有一个项目与 ItemID 匹配的情况,请使用 Single。 如果有多个项不是无效的,并且你想要正常处理没有匹配项,请使用 FirstOrDefault 并在使用之前检查生成的项是否为 null。

如果您预计集合中不会出现指定的值并且这不是例外情况,那么最好使用第二种情况.FirstOrDefault()

另请注意,Find() 是一种List<T>方法,而不是Where()是一种扩展方法,可以应用于实现IEnumerable<T>的任何类型,因此通过在代码中使用Where()您可以获得更大的灵活性。