这两个 LINQ 查询有什么区别以及如何正确优化它们?

What is the difference between these two LINQ Queries and how to correctly optimize them?

我有一个客户 table,其中包含以下列: 身份证、名字、姓氏、货币 ID、性别。

我想要 select 对应于 Id 10 的客户货币,所以我正在做这样的事情:

var currencyId = Db.Clients.FirstOrDefault(c=>c.Id == 10)?.CurrencyId;

这一行是从 Db 获取所有属性并且 selects 代码中的货币还是在数据库中执行类似这样的操作:

SELECT currencyId FROM Client WHERE ID = 10

或者我应该这样写 linq:

var currencyId = Db.Clients.Where(c=>c.Id == 10).Select(c=>c.CurrnecyId).FirstOrDefault();

这两个查询有什么区别? 将上述 SQL 查询转换为 linq 查询的正确方法是什么?

我自己调查了一下,因为我发现大多数人的回答都是有问题的。我希望 FirstOrDefault 实现结果(您还可以从类型中看到您不再使用查询对象),所以这意味着它查询所有属性。

与第二个查询不同,您在过滤您喜欢的 属性 时仍在使用查询,因此取决于实现,它可用于过滤属性和选择特定字段。

以下是使用 EF 为两个相似查询生成的查询示例,其中显示了两个生成不同的查询:https://dotnetfiddle.net/5aFJAZ

在您的第一个示例中,var currencyId = Db.Clients.FirstOrDefault(c=>c.Id == 10)?.CurrencyId; 查询选择整个对象到内存,然后 returns 从内存对象中的 ID 属性。因此,它需要执行如下操作 SQL:SELECT * FROM Clients WHERE Id = 10。我知道我在这里没有使用参数,EF 会拼出每一列。然而,这里要理解的关键是,通过返回比您需要的更多的列,您可能会设置性能问题,因为不会使用 Id 和 CurrencyId 的覆盖索引。

您的第二个 LINQ 查询将使用 SQL 语句,如 SELECT CurrencyId FROM Clients Where Id = 10,假设您有一个覆盖这些列的索引,它将利用您的索引。