C# EF 如何包含已用作子列表的实体<>

问题描述 投票:0回答:1

我是 EF 新手,我有点困惑..

我有这些实体:

class Employee
{
    public Guid Id { get; set; }
    public string? Login { get; set; }
    
    public string? FirstName { get; set; }
    public string? LastName { get; set; }
    public string? MidName { get; set; }
    
    public Guid? DepartmentId { get; set; }
    public Department? Department { get; set; }
    
    public Guid? OrganizationId { get; set; }
    public Organization? Organization { get; set; }
    
    public Guid? StateId { get; set; }
    public State? State { get; set; }
}

class Department
{
    public Guid Id { get; set; }
    public string? Name { get; set; }
    public string? ShortName { get; set; }

    public Guid? ParentDepartmentId { get; set; }
    public Department? ParentDepartment { get; set; }

    public List<Employee> Employees { get; set; } = new();
    
    public Guid ManagerID { get; set; }
    public Employee Manager { get; set; }

    public Guid? StateId { get; set; }
    public State? State { get; set; }
}

现在由于

Manager
属性,我无法添加迁移并收到此错误消息:

无法创建“BlazorTest.Components.Data.DataContext”类型的“DbContext”。异常“无法确定类型为“List”的导航“Department.Employees”所表示的关系。手动配置关系,或者使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性

遇到这种情况该如何处理?预先感谢您!

尝试了 FluentApi 代码的许多变体,但由于我是 EF 的新手,所以我陷入了困境......

我使用PostgresSQL

附注很抱歉打扰了这个问题,但我只花了两周时间......

c# postgresql entity-framework entity-framework-core migration
1个回答
0
投票

有两件事:EF 可以按照约定计算关系,但默认根据类型名称而不是属性名称解析 FK 属性。我建议始终使用

[ForeignKey]
属性来确保 EF 使用存在 FK 属性的预期值:

public Guid? ParentDepartmentId { get; set; }
[ForeignKey(nameof(ParentDepartmentId))]
public Department? ParentDepartment { get; set; }

public Guid ManagerID { get; set; }
[ForeignKey(nameof(ManagerID))]
public Employee Manager { get; set; }

接下来,员工和部门之间有两种关系,一对多(部门.员工/员工.部门)和可能是一对一的关系。 (Department.Manager) 问题是 EF 不知道 Employee.Department 是否属于 Department.Employees 或 Department.Manager 的另一端,因此您需要显式配置它。如果您有

IEntityTypeConfiguration
实施或
OnModelCreating
实施,那么您可以通过在部门配置上设置
.HasMany(x => x.Employees).WithOne(x => x.Department)
来实现,或使用
[InverseProperty]
:

[InverseProperty(nameof(Employee.Department))]
public List<Employee> Employees { get; set; } = new();

...这应该会让 EF 高兴。

© www.soinside.com 2019 - 2024. All rights reserved.