c# - Linq,select().SingleorDefault() 是个坏主意吗?

标签 c# asp.net linq

 var queueitem = context.CrawlerQueues.
                 Select(cq => new{cq.Guid,cq.Result}).
                 SingleOrDefault(cq => cq.Guid == guid);

这是一个坏主意,它会先选择所有数据库行,然后找到一个行,还是会聪明地查看其使用的上下文,然后只获取一行。

这样做的原因是我只想返回 Guid 和结果列。

return Newtonsoft.Json.JsonConvert.SerializeObject(queueitem, Formatting.Indented);

我如何在不必监视网络流量或对数据库发出的请求的情况下找到这个问题的答案?

最佳答案

“它会先选择所有数据库行然后找到一个”

从技术上讲,不,.Select 后跟 .SingleOrDefault 的组合不会这样做。 Select() 为查询设置参数,但实际上并不获取任何数据。 LINQ 的延迟执行在实际必须产生数据结果之前不会获取任何行。您可以将多个查询组合在一起(.Select(...).Select(..) 等),在您执行返回数据的操作(例如 First() 或 .ToList())之前,实际上不会获取任何行。

但是,使用 Single() 可能会导致扫描整个数据集以证明匹配行是唯一匹配行。

想一想:查询如何知道这一行是数据集中匹配的唯一行?它将不得不尝试找到下一行。如果真的只有一行与数据集中的数百万行匹配,则 Single() 可能必须遍历所有这数百万行以证明当前匹配是唯一匹配。

如果您的数据集是 SQL,并且您的数据以允许查询优化的方式建立索引,那么 Single() 可能还不错。但是,如果您的 SQL 数据未以有助于此查询的方式编制索引,则 Single() 可能会为 SQL 服务器创建大量工作。

如果您的程序逻辑确实需要知道返回的行是整个数据集中的唯一行,则 Single() 是合适的。但是,还有其他方法可以保证唯一性。如果您可以在与您的 LINQ 条件匹配的数据上设置一个主键,那么只有一个匹配行可以存在/添加到数据库中,因此您实际上不需要 Single()。 (具有讽刺意味的是,在这种情况下,Single() 的性能也会非常快,因为主键索引可用于优化查询)

如果您只想要匹配条件的第一行,请使用 First() 而不是 Single()。 First() 只需扫描数据行,直到找到第一个匹配项。它不必继续扫描行来证明第一个匹配项是唯一匹配项,如 Single()。

关于c# - Linq,select().SingleorDefault() 是个坏主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9074959/

相关文章:

c# - 如何在 ASP.NET Web API 异步 Controller 方法中返回对象列表

c# - 将位图转换为 ASP.NET 的图像

c# - Asp.Net 连接表,以便它们可以正确排序 C# LINQ

c# - 使用 C# 停止 QTP 执行

c# - 操作无法完成。无效指针 - VS2010 SP1

c# - LINQ 的嵌套组

c# - Sitecore 内容搜索,转换为 List<item> 并编辑

c# - 如何为 C# <proto/> 定义传递experimental_allow_proto3_optional 以在proto3 中启用optional?

C# Xamarin : How to change navigation bar color?

c# - 将对数据网格所做的更改反射(reflect)回数据集和数据表