【问题标题】:EF Core retrieves entity with null property from foreign-key to same modelEF Core 从外键检索具有空属性的实体到同一模型
【发布时间】:2020-12-15 21:24:17
【问题描述】:

当我查询数据库以检索记录,并且模型包含一个属性,该属性是同一类型的外键时,该属性返回 null。我做错了什么?

我有这个模型类:

public class Customer
{
    public int ID { get; set; }
    
    [ForeignKey("ParentID")]
    public virtual Customer Parent { get; set; }

    public List<Contact> Contacts { get; set; }

    [Required]
    public string Name { get; set; }
}

与基础表:

CREATE TABLE [dbo].[Customer] 
(
    [ID]       INT IDENTITY (1, 1) NOT NULL,
    [ParentID] INT NULL,
    [Name]     NVARCHAR(MAX) NOT NULL,

    CONSTRAINT [PK_Customer] 
        PRIMARY KEY CLUSTERED ([ID] ASC),
    CONSTRAINT [FK_Customer_Customer_ParentID] 
        FOREIGN KEY ([ParentID]) REFERENCES [dbo].[Customer] ([ID])
)

这是使用 EF Core 代码先迁移生成的。

当CustomersController 尝试:

public async Task<IActionResult> Details(int? id)
{
    if (id == null)
    {
        return NotFound();
    }

    // returns the correct customer with null Parent property which causes...
    var customer = await _context.Customer
                                 .FirstOrDefaultAsync(m => m.ID == id); 

    if (customer == null)
    {
        return NotFound();
    }

    var vm = new CustomerViewModel(customer); // ... NRE to be thrown here

    return View(vm);
}

即使该数据存在于表中:

ID  ParentID  Name
--------------------------
5   1         ParentCo
7   5         ChildCo

【问题讨论】:

    标签: asp.net-mvc entity-framework-core asp.net-core-3.1


    【解决方案1】:

    试试这个

    var result = await _context.Customer.Include(x => x.Parent).FirstOrDefaultAsync(x => x.Id == id);
    
    

    但如果这不起作用

    var customer = await _context.Customer.FirstOrDefaultAsync(
            .FirstOrDefaultAsync(m => m.ID == id); );
    
    if (customer != null)
    {
       var parent = await _context.Customer.FirstOrDefaultAsync(x => x.ParentId == customer.Id);
    
       if (parent != null)
       {
           customer.Parent = parent;
       }
    }
    else
    {
        return NotFound();
    }
    
    
    

    【讨论】:

    • 谢谢@Gabriel。您的第一个建议效果很好。但是实体框架没有自动执行此操作的机制吗?为什么不呢?
    • @khargosh 它被映射为外部表,Include(...) 被转换为SQL Join statement。不自动包含它的原因是为了性能。如果您的 Customer 表中自动包含 6-7 个表,则进行成像。所以目的是将查询限制在主表中,通过Include,您只会添加需要的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-05-26
    • 2022-12-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多