如何在 EFCore 3.1 中创建完美封装的一对一父子关系?

Posted

技术标签:

【中文标题】如何在 EFCore 3.1 中创建完美封装的一对一父子关系?【英文标题】:How to create a perfectly encapsulated 1-to-1 parent-child relation in EFCore 3.1? 【发布时间】:2021-04-01 00:40:17 【问题描述】:

假设我要代表以下业务领域:

每辆车都有一个里程表 每个里程表都属于一辆车 汽车知道里程表 里程表不了解汽车

我理想的 OOP 表示是这样的

public class Car

    public Guid Id  get; 
    public Odomoeter Odomoeter  get; 

    private Car(Guid id, Odometer odometer)
    
         this.Id = id;
         this.Odometer = odometer;
    

    public static Car CreateNew(Guid id) => new Car(id, Odometer.CreateNew(id));


public class Odometer

    public int Miles
    
       get => this._miles;
       set
       
           if (value < this._miles)
              throw new InvalidOperationException("Cannot wind back odometer! ILLEGAL!");
           this._miles = value;
       
    

    private int _miles;

    private Odometer(Guid id, int miles)
    
        this.Id = id;
        this._miles = miles;
    

    public static Odometer CreateNew(Guid id) => new Odometer(id, 0);

而不是像贫血一样

public class Car

    public Guid Id  get; set; 
    public Odomoeter Odomoeter  get; set; 
    public Guid OdometerId  get; set; 


public class Odometer

    public Guid Id  get; set; 
    public int Miles  get; set; 
    public Car Car  get; set; 
    public Guid CarId  get; set; 

但是,我不确定这是否可以通过HasOne...WithOne..etc. 流利的语法实现。看来您需要在父母和孩子之间进行双向参考。我知道 SQL 表应该是什么样子,非常简单:

       Car
=================
 Id | OdometerId

     Odometer
=================
  Id | Miles

但是,将它连接到我的封装模型一直很痛苦。

【问题讨论】:

【参考方案1】:

这个配置应该可以正常工作

public class CarConfiguration : IEntityTypeConfiguration<Car>

    public void Configure(EntityTypeBuilder<Car> builder)
    
        builder.HasOne(x => x.Odometer)
                .WithOne();

        builder.HasKey(x => x.ID);
    

不完全确定,但您可能还需要一个没有Odometer 的汽车构造函数,否则 EF Core 很可能会引发异常。它有不同的机制来附加导航属性。

private Car(Guid id)

    this.Id = id;

【讨论】:

以上是关于如何在 EFCore 3.1 中创建完美封装的一对一父子关系?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 或实体框架中创建没有主键的一对多关系?

如何在 EF 中创建从两个表到一个源的一对一映射?

如何在android中创建弯曲的底部边框矩形?

如何在efcore中设计一对多关系?

EF Core 5 在迁移中创建了两次表

如何在没有主键的情况下从连接表中创建实体