【问题标题】:How do I fix one to many relationship where one side has two entities of the same type如何修复一侧具有两个相同类型实体的一对多关系
【发布时间】:2019-04-05 13:52:47
【问题描述】:

我正在做一个项目。当我第一次开始时,我有一个订单模型和地址模型。但是,现在我想将 Order 模型更改为具有 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 列 AddressToId 和 AddressFromId,而不仅仅是 AddressId(现在就是这样)。

非常感谢社区在这方面的帮助。

【问题讨论】:

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


    【解决方案1】:

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

    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; }
    }
    

    然后将AddressFromId 和AddressToId 属性添加到您的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);
        }
    }
    

    然后在DbContext的OnModelCreating中如下:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
         base.OnModelCreating(modelBuilder);
    
         modelBuilder.ApplyConfiguration(new OrderConfiguration());  
    }
    

    【讨论】:

    • 您好,感谢您的回复。尝试您的解决方案时出现此错误。访问“程序”类上的 IWebHost 时出错。在没有应用程序服务提供商的情况下继续。错误:无法确定“ICollection”类型的导航属性“Address.Order”表示的关系。手动配置关系,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性。
    • @Endkey 您还没有从Address 模型类中删除public virtual ICollection&lt;Order&gt; Order { get; set; }?请仔细阅读我的回答。我在一个测试项目中完美地生成了所有东西。所以它肯定也会对你有用。
    • 我已经做到了。我也对错误消息感到惊讶。但这就是我按照您的所有步骤得到的结果
    • 您的解决方案似乎奏效了。我得到了我想要的数据库中的列。版本存在一些问题,只是 Visual Studio 没有获取元数据文件,这使得 Nuget 包控制台一次又一次地显示相同的错误。非常感谢你的帮助!真的很感激!
    【解决方案2】:

    你可以这样配置:

    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 的实体吗?如果没有,您可以从中删除 AddressId 和 Order 属性,并使其成为 Order 实体的 owned entity:

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

    更新:删除订单映射

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

    【讨论】:

    • 你这modelBuilder.Entity&lt;Order&gt;().HasOne(x =&gt; x.AddressTo).WithMany(x =&gt; x.Order); //Add HasForeignKey, IsRequired... if you want modelBuilder.Entity&lt;Order&gt;().HasOne(x =&gt; x.AddressFrom).WithMany(x =&gt; x.Order);这两行是完全错误的。您不能将两个外键指向一个导航属性。
    • 嗨!感谢您的回复。这是我现在得到的错误,使用您提供的第一个解决方案访问“程序”类上的 IWebHost 时发生错误。在没有应用程序服务提供商的情况下继续。错误:无法确定“ICollection”类型的导航属性“Address.Order”表示的关系。手动配置关系,或使用“[NotMapped]”属性或使用“OnModelCreating”中的“EntityTypeBuilder.Ignore”忽略此属性。
    猜你喜欢
    • 2011-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多