实体框架 FirstOrDefault 谓词未返回预期结果

Posted

技术标签:

【中文标题】实体框架 FirstOrDefault 谓词未返回预期结果【英文标题】:Entity Framework FirstOrDefault predicate not returning expected results 【发布时间】:2021-10-15 00:07:32 【问题描述】:

我正在学习 C# 和 ASP.NET Core。

我有一个带有Guid 类型键的模型类:

public class Product

    [Key]
    [Required]
    public Guid Id  get; set; 
    ...

我有一个带有数据库上下文的存储库。我正在尝试按此 Guid 进行搜索,但找不到任何结果。

public Product GetProductById(Guid id) 

    foreach (var product in _context.Products.ToList()) 
    
        Console.WriteLine("id: 0, search: 1, match: 2", product.Id, id, product.Id == id);
    

    return _context.Products.FirstOrDefault(p => p.Id == id);

上述方法输出以下内容,但返回 null Product

id: ad253f3e-bf32-4b17-a667-4de1c70175be, search: 80e0ca0a-fbec-495a-b008-557586511de0, match: False
id: 80e0ca0a-fbec-495a-b008-557586511de0, search: 80e0ca0a-fbec-495a-b008-557586511de0, match: True
id: da51a147-4b28-48a1-8b0a-fe7876df6a58, search: 80e0ca0a-fbec-495a-b008-557586511de0, match: False
id: 786f1c64-815f-4e80-a441-e5ea09ad16ca, search: 80e0ca0a-fbec-495a-b008-557586511de0, match: False
id: 81bbbb96-1290-479b-9cf6-e18b21500d71, search: 80e0ca0a-fbec-495a-b008-557586511de0, match: False

我的查询是否有错误或问题?

编辑 cmets 中的 David 要求提供更多信息。

来自日志的 SQL 查询:

dbug: 12/8/2021 15:10:01.496 RelationalEventId.ConnectionOpening[20000] (Microsoft.EntityFrameworkCore.Database.Connection) 
      Opening connection to database 'main' on server 'refactored.db'.

dbug: 12/8/2021 15:10:01.518 RelationalEventId.ConnectionOpened[20001] (Microsoft.EntityFrameworkCore.Database.Connection) 
      Opened connection to database 'main' on server '/home/kevin/Desktop/XeroApplication/RefactoredProject/src/Refactored/refactored.db'.

dbug: 12/8/2021 15:10:01.532 RelationalEventId.CommandExecuting[20100] (Microsoft.EntityFrameworkCore.Database.Command) 
      Executing DbCommand [Parameters=[@__id_0='?'], CommandType='Text', CommandTimeout='30']
      SELECT "p"."Id", "p"."DeliveryPrice", "p"."Description", "p"."Name", "p"."Price"
      FROM "Products" AS "p"
      WHERE "p"."Id" = @__id_0
      LIMIT 1

info: 12/8/2021 15:10:01.563 RelationalEventId.CommandExecuted[20101] (Microsoft.EntityFrameworkCore.Database.Command) 
      Executed DbCommand (33ms) [Parameters=[@__id_0='?'], CommandType='Text', CommandTimeout='30']
      SELECT "p"."Id", "p"."DeliveryPrice", "p"."Description", "p"."Name", "p"."Price"
      FROM "Products" AS "p"
      WHERE "p"."Id" = @__id_0
      LIMIT 1
      
dbug: 12/8/2021 15:10:01.571 RelationalEventId.DataReaderDisposing[20300] (Microsoft.EntityFrameworkCore.Database.Command) 
      A data reader was disposed.

以及来自 SQLite 的表架构

CREATE TABLE IF NOT EXISTS "Products" (
    "Id" TEXT NOT NULL CONSTRAINT "PK_Products" PRIMARY KEY,
    "Name" TEXT NOT NULL,
    "Description" TEXT NOT NULL,
    "Price" TEXT NOT NULL,
    "DeliveryPrice" TEXT NOT NULL
);

【问题讨论】:

对我来说看起来是正确的,除非是延迟加载数据的问题 如果您注释掉循环,它是否仍然返回null 产品? (即:如果您评论 .ToList() 电话) 什么数据库?你能贴出表 DDL 和日志记录生成的 SQL 查询吗? docs.microsoft.com/en-us/ef/core/logging-events-diagnostics/… Rafalon,我正在使用 SQLite。大卫,已将该信息添加到问题中。谢谢:) 【参考方案1】:

试试这个

 return _context.Products
    .Where((p => p.Id.ToString() == id.ToString())
    .FirstOrDefault)

【讨论】:

感谢 Muhammad,但我在这个实现中遇到了这个错误 `System.InvalidOperationException: The LINQ expression 'DbSet() .Where(p => p.Id.ToString() == __ToString_0 )' 无法翻译。附加信息:方法“object.ToString”的翻译失败。` 您使用的是什么版本的 EF?

以上是关于实体框架 FirstOrDefault 谓词未返回预期结果的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 4 Single() vs First() vs FirstOrDefault()

实体框架对象上下文刷新

实体框架查询——加载数据优化

如何使用实体框架获取记录计数匹配谓词

核心数据:返回另一个实体的对象的谓词

All 子句核心数据谓词未按预期工作