首页 > 解决方案 > 两个模型之间的关系错误在 asp.net core 2.1 中有更多的键

问题描述

问题:

从 'SalesFooter.SaleHeaders' 到 'SalesHeader.SalesFooters' 与外键属性 {'SalesOrderNo' : int} 的关系不能定位主键 {'SalesOrderNo' : int, 'SalesType' : int, 'SalesYear' : int, ' BranchCode' : int} 因为它不兼容。为此关系配置一个主键或一组兼容的外键属性。

细节:

我在 ASP.NET Core、Entity Framework Core 2.1 和 Visual Studio 2017 中工作。当我在两个模型 SalesHeader 和 SalesFooter 之间建立如下关系时,会出现上述错误:

public class SalesHeader  
{        

        public int SalesOrderNo { get; set; }  


        public int SalesYear { get; set; }  


        public int BranchCode { get; set; }  


        public int SalesType { get; set; }  
        [Required]  

        public DateTime SalesDate { get; set; }  
        public ICollection<SalesFooter> SalesFooters { get; set; }  

}

public class SalesFooter  
{  

        public int SalesOrderNo { get; set; }  

        public int SalesYear { get; set; }  

        public int BranchCode { get; set; }  

        public int SalesType { get; set; }  

        public int SalesLineNo { get; set; }  
        [Required]  

        public DateTime SalesDate { get; set; }  
        [DataType("decimal(18 ,2")]  
        public decimal Quantity { get; set; }  
        [DataType("decimal(18 ,2")]  
        public decimal UnitPrice { get; set; }  
        [DataType("decimal(18 ,2")]  
        public decimal Total { get; set; }  


        public SalesHeader SaleHeaders{ get; set; }  
}

protected override void OnModelCreating(ModelBuilder modelBuilder)  
{  
     base.OnModelCreating(modelBuilder);  

     modelBuilder.Entity<SalesHeader>()  
                .HasKey(t => new { t.SalesOrderNo,t.SalesType,t.SalesYear,t.BranchCode });  
     modelBuilder.Entity<SalesFooter>()  
                .HasKey(t => new { t.SalesOrderNo, t.SalesType, t.SalesYear, t.BranchCode,t.SalesLineNo});  
     modelBuilder.Entity<SalesFooter>().HasOne(e => e.SaleHeaders)  
                     .WithMany(e => e.SalesFooters)  
                     .HasForeignKey(e => e.SalesOrderNo);      
 }  

如何根据上面的键在两个模型之间建立关系?

样本数据:

SalesHeader 表

…………………………………………………………………………………………………………………………………………

SalesOrderNo  SalesYear  BranchCode SalesType  CustomerID  
50              2018        1          1          20  

销售页脚表

.....................................

SalesOrderNo SalesLineNo  SalesYear  BranchCode SalesType  ItemCode  
50                1          2018        1          1          1001  
50                2          2018        1          1          1002  
50                3          2018        1          1          1003 

标签: c#asp.netasp.net-mvcentity-framework-coreentity-relationship

解决方案


这里

.HasForeignKey(e => e.SalesOrderNo)

您是在告诉 EF Core 使用单个属性(列)SalesFooter.SalesOrderNo作为SalesHeader. 但SalesHeader使用复合 PK {SalesOrderNo, SalesType, SalesYear, BranchCode}

FK的类型和参考 PK 必须匹配。这意味着您需要设置复合 FK {SalesOrderNo, SalesType, SalesYear, BranchCode}

您可以通过简单地删除整个

modelBuilder.Entity<SalesFooter>()
    .HasOne(e => e.SaleHeaders)
    .WithMany(e => e.SalesFooters)  
    .HasForeignKey(e => e.SalesOrderNo);

或者只是

    .HasForeignKey(e => e.SalesOrderNo)

流畅的配置,因为您的模型/关系遵循 EF Core 约定,因此 EF Core 可以自动识别与所涉及的正确导航/FK/PK 属性的关系。

但是,如果您想明确,请使用与定义复合 PK 相同的语法:

modelBuilder.Entity<SalesFooter>()
    .HasOne(e => e.SaleHeaders)
    .WithMany(e => e.SalesFooters)  
    .HasForeignKey(e => new { e.SalesOrderNo, e.SalesType, e.SalesYear, e.BranchCode }); // <--

推荐阅读