gpt4 book ai didi

entity-framework - EF Where(x => x.ColumnVal == 1) vs FirstOrDefault(x => x.Column == 1)

转载 作者:行者123 更新时间:2023-12-04 08:35:02 26 4
gpt4 key购买 nike

我有一个加载对象层次结构的 LINQ 查询,如下所示。

查询 #1

var result = db.Orders
.Include("Customer")
// many other .Include() here
.FirstOrDefault(x => x.Customer.CustomerId == 1 &&
x.OrderId == orderId);

我有 主要性能问题 用它。
CPU 使用率接近 100%,内存使用率非常高。

我将其调整为以下内容并修复了性能问题。

查询 #2
var result = db.Orders
.Include("Customer")
// many other .Include() here
.Where(x => x.Customer.CustomerId == 1 &&
x.OrderId == orderId)
.FirstOrDefault();

我只是想证实我的怀疑。
查询 #1 可能会遍历我所有的记录 在内存中 寻找匹配的记录
对比
查询#2 过滤数据库上的记录,然后只获取第一条记录。

这就是为什么 查询 #1 有性能问题吗?

为了安全起见,我是否需要使用 .Select(x => x)之前 .FirstOrDefault() ?

查询 #3
var result = db.Orders
.Include("Customer")
// many other .Include() here
.Where(x => x.Customer.CustomerId == 1 &&
x.OrderId == orderId)
.Select(x => x)
.FirstOrDefault();

最佳答案

不,它们在执行时都应该产生相同的 SQL 查询。您可以通过查看 SQL Profiler 来证明这一点,并查看在这两种情况下从 EF 提交的确切 SQL 是什么。您的性能优化应该是由其他一些因素引起的。原因如下:

Include 方法返回 ObjectQuery<T> :

public class ObjectQuery<T> : ObjectQuery, IOrderedQueryable<T>, 
IQueryable<T>, IEnumerable<T>,
IOrderedQueryable, IQueryable,
IEnumerable, IListSource

这意味着它的 FirstOrDefault 方法带有 2 个重载:
// Defined by Enumerable:
FirstOrDefault(Func<T, Boolean>)

// Defined by Queryable:
FirstOrDefault(Expression<Func<T, Boolean>>)

当您编码时 .FirstOrDefault(x => x.Customer.CustomerId == 1编译器将进入一个名为 的进程过载解析推断 lambda 表达式的类型 x => x.Customer.CustomerId == 1因为它可以转换为两个重载参数类型的类型。

编译器将使用一种算法(我仍在尝试在 C# 语言规范中找到它!),弄清楚将 lambda 转换为 Expression<Func<T, Boolean>更好的转换比到 Func<T, Boolean>所以选择 IQueryable 重载。

因此,在 SQL Profiler 中观察时,您将看到生成的 SQL 中的谓词。

关于entity-framework - EF Where(x => x.ColumnVal == 1) vs FirstOrDefault(x => x.Column == 1),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4047266/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com