好处 之间 .ToList().第一节 .单用于 C# 中的 IQueryable

本文关键字:用于 IQueryable 单用于 中的 ToList 之间 好处 一节 | 更新日期: 2023-09-27 18:35:14

所以我正在对 NOSQL 数据库运行一个 linq 查询,如果存在一个具有该 Id 的对象,则应该只返回一个对象,如果不存在,则什么都不返回,但数据库中可能有两个具有相同 id 的对象(如果其他人搞砸了。目前我已经实现了如下:

(from c in [IQueryableThing] where c.Id.Equals(id)).ToList().First()

我也考虑过替代方案

(from c in [IQueryableThing] where c.Id.Equals(id)).Single()

我假设.Single() 更快,但我担心它们都不处理数据库中没有具有正确 id 的对象的情况。我不在乎是否有不止一个返回。我只想要其中之一。最终,我将实现一些东西来返回最近修改的内容。

基本上,我的问题是解决将可查询对象转换为单个实例的问题的最佳方法是什么,该处理方式是处理没有具有正确id的对象并且有多个具有正确id的对象的情况。

好处 之间 .ToList().第一节 .单用于 C# 中的 IQueryable

听起来你只是想称呼FirstOrDefault(),这完全符合顾名思义。
Default意味着null

你不应该调用ToList();这将不必要地从数据库下载所有结果。

使用 IQueryable.Single 更有效:

  • 调用 ToList 枚举整个结果集,并将每个项存储在内存中的单个连续数组中。然后,First只从数组中获取第一项。
  • 调用 IQueryable.Single 仅计算列表中的第一项,如果未返回任何项,则引发异常。然后,它会检查结果集中是否有其他项,如果有项,则引发异常。

如果您想处理集合中不存在符合您条件的项目的情况,但不关心是否有多个项目,我强烈建议改用FirstOrDefault

var result = (from c in [IQueryableThing] where c.Id.Equals(id)).FirstOrDefault();
if (result == null)
{
    // no items found
}

这将转换为 SQL 中的TOP 1,并仅返回结果集中的第一项,或者如果结果集为空,它将仅返回 null(如果您正在处理结构,则返回默认值)。

.ToList()应该没有区别,它只会将可查询枚举到内存中列表中。 对于您的情况,您有多种选择。 您展示的两个行为非常不同:

  • .First() - 这将返回枚举中的第一个元素,如果没有元素,则引发异常。
  • .Single() - 这将返回枚举中唯一的元素,如果没有元素或有多个元素,则会引发异常。
  • .FirstOrDefault() - 这将返回枚举中的第一个元素,如果没有,则返回默认值(对于引用类型null)。
  • .SingleOrDefault() - 这将返回枚举中的唯一元素,如果没有,则返回默认值(对于引用类型null),如果有多个元素,则引发异常。

听起来你想用.FirstOrDefault(). 检查结果是否null。 如果是,则没有匹配的元素。 如果不是,则具有第一个匹配的元素。

我相信你正在寻找Enumerable.FirstOrDefault

返回序列的第一个元素,如果 序列不包含任何元素。

你应该使用.FirstOrDefault(c => c.ID.Equals(id));

如果未找到任何内容(类的默认值为 null),它将返回默认值或它找到的第一个默认值。

如果您确定存在一个且只有一个项目,并且您需要使用 Single()

如果您不确定将使用 First() 或 FirstOrDefault() 返回多少项。

不同之处在于,如果存在多个项目,Single() 将引发异常。如果您想在没有唯一约束的情况下在数据库上捕获插入错误等,则非常有用。