使用 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 的最佳解决方案。 无论哪种方式,对最佳方法的解释都会有所帮助,因为我经常检索单个业务对象项。何时使用哪个功能也很棒。谢谢。
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()
您可以获得更大的灵活性。