如何解决一对多关系,其中一侧有两个相同类型的实体

时间:2019-04-05 13:52:48

标签: c# entity-framework-core one-to-many ef-fluent-api

我正在做一个项目。刚开始时,我有一个订单模型和地址模型。但是,现在,我想将订单模型更改为具有AddressTo和AddressFrom,而不仅仅是Address。

地址模型:

public class Address
{
    public int AddressId { get; set; }
    public int ZipCodeId { get; set; }
    public string Street { get; set; }
    public int Nr { get; set; }
    public virtual ICollection<Order> Order { get; set; }
    public virtual ZipCode ZipCode { get; set; }
} 

订单模型:

public class Order
{   
    public int OrderId { get; set; }
    public int CustomerId { get; set; }
    public virtual Address Address { get; set; }
    public DateTime OrderDate { get; set; } 
    public DateTime SentDate { get; set; } 
    public string Title { get; set; }
    public string Type { get; set; }
    public string Content { get; set; }
    public int ExpectedHours { get; set; }
    public int AmountWorkers { get; set; }
    public virtual Customer Customer{ get; set; }
}

我想要的订单:

public class Order
{   
    public int OrderId { get; set; }
    public int CustomerId { get; set; }
    public virtual Address AddressTo { get; set; }
    public virtual Address AddressFrom { get; set; }
    public DateTime OrderDate { get; set; } 
    public DateTime SentDate { get; set; } 
    public string Title { get; set; }
    public string Type { get; set; }
    public string Content { get; set; }
    public int ExpectedHours { get; set; }
    public int AmountWorkers { get; set; }
    public virtual Customer Customer{ get; set; }
}

我已经意识到,没有FluentApi就不可能解决这个问题。但是,我发现很难克服这个问题。

我想要的是数据库中的Order表,以显示ID列AddressToIdAddressFromId,而不是AddressId(现在就是这样)。

非常感谢社区对此提供的帮助。

2 个答案:

答案 0 :(得分:0)

您可以这样配置它:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  // ...
  modelBuilder.Entity<Order>().HasOne(x => x.AddressTo).WithMany(); //Add HasForeignKey, IsRequired... if you want
  modelBuilder.Entity<Order>().HasOne(x => x.AddressFrom).WithMany(); //Add HasForeignKey, IsRequired... if you want 
  //...
}

但是您甚至需要Address才能成为具有ID的实体吗?如果没有,则可以从其中删除AddressIdOrder属性,并使其成为Order实体的owned entity

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
  // ...
  modelBuilder.Entity<Order>().OwnsOne(x => x.AddressTo);
  modelBuilder.Entity<Order>().OwnsOne(x => x.AddressFrom);
  //...
}

更新:已删除订单映射

您可以从Order类中删除Address属性,而只需在映射中使用不带参数的.WithMany()

答案 1 :(得分:0)

首先从public virtual ICollection<Order> Order { get; set; }模型类中删除Address导航属性,如下所示:

public class Address
{
    public int AddressId { get; set; }
    public int ZipCodeId { get; set; }
    public string Street { get; set; }
    public int Nr { get; set; }

    public virtual ZipCode ZipCode { get; set; }
}

然后将AddressFromIdAddressToId属性添加到Order模型类中,如下所示:

public class Order
{
    public int OrderId { get; set; }
    ..............
    public int AddressFromId { get; set; }
    public virtual Address AddressFrom { get; set; }

    public int AddressToId { get; set; }
    public virtual Address AddressTo { get; set; }

    ................
}

然后按如下所示配置您的Order

public class OrderConfiguration : IEntityTypeConfiguration<Order>
{
    public void Configure(EntityTypeBuilder<Order> builder)
    {
        builder.HasOne(o => o.AddressFrom).WithMany().HasForeignKey(o => o.AddressFromId)
            .OnDelete(DeleteBehavior.Restrict);

        builder.HasOne(o => o.AddressTo).WithMany().HasForeignKey(o => o.AddressToId)
            .OnDelete(DeleteBehavior.Restrict);
    }
}

然后在OnModelCreating的{​​{1}}中进行如下操作:

DbContext