C# 一对多映射中的实体框架核心复合键

C# 一对多映射中的实体框架核心复合键,c#,entity-framework-core,C#,Entity Framework Core,因此,在我们有两个类的地方出现了一个映射问题 public class Customer { public int Id; public CustomerAddress StatementAddress public bool AlwaysTrue => true; public string Code; } public class CustomerAddress { public int Id; public bool ForState

因此,在我们有两个类的地方出现了一个映射问题

public class Customer
{
    public int Id;
    public CustomerAddress StatementAddress
    public bool AlwaysTrue => true;
    public string Code;
}

public class CustomerAddress
{
    public int Id;
    public bool ForStatement;
    public string _CustomerCode
}
我们的映射设置如下所示:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Customer>()
        .HasOne(s => s.StatementAddress)
        .WithMany()
        .HasPrincipalKey(x=> new {x._CustomerCode, x.ForStatement})
        .HasForeignKey(s => new { s.Code, s.AlwaysTrue});
}
public class Customer
{
    public int Id;
    public CustomerAddress StatementAddress;
    [Column("StatementAddress_ForStatement")]
    public bool AlwaysTrue => true;
    [Column("StatementAddress_CustomerCode")]
    public string Code;
}
public class Customer
{
    public int Id;
    public CustomerAddress StatementAddress;
    [ForeignKey("StatementAddress"), Column(Order = 1)]
    public bool AlwaysTrue => true;
    [ForeignKey("StatementAddress"), Column(Order = 0)]
    public string Code;
}
模型创建时受保护的覆盖无效(ModelBuilder ModelBuilder)
{
modelBuilder.Entity()
.HasOne(s=>s.StatementAddress)
.有很多
.HasPrincipalKey(x=>new{x.\u CustomerCode,x.ForStatement})
.HasForeignKey(s=>new{s.Code,s.AlwaysTrue});
}
然而,这导致了一个问题,因为它似乎是在数据库中寻找一列StatementAddress\u CustomerCode和StatementAddress\u for Customer表中的statement,这显然不是存在的东西-为什么它不寻找代码表并简单地为AlwaysTrue传递True呢


我本以为它的定义键只会使用Code和Alwaystrue值,但似乎在寻找由属性名组合而成的两列,并附加来自另一个类的属性名=/

,我在这里建议两件事:

  • 您可以这样手动定义列名:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>()
            .HasOne(s => s.StatementAddress)
            .WithMany()
            .HasPrincipalKey(x=> new {x._CustomerCode, x.ForStatement})
            .HasForeignKey(s => new { s.Code, s.AlwaysTrue});
    }
    
    public class Customer
    {
        public int Id;
        public CustomerAddress StatementAddress;
        [Column("StatementAddress_ForStatement")]
        public bool AlwaysTrue => true;
        [Column("StatementAddress_CustomerCode")]
        public string Code;
    }
    
    public class Customer
    {
        public int Id;
        public CustomerAddress StatementAddress;
        [ForeignKey("StatementAddress"), Column(Order = 1)]
        public bool AlwaysTrue => true;
        [ForeignKey("StatementAddress"), Column(Order = 0)]
        public string Code;
    }
    
  • 您可以使用
    ForeignKeyAttribute
    指定外键,如下所示:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Customer>()
            .HasOne(s => s.StatementAddress)
            .WithMany()
            .HasPrincipalKey(x=> new {x._CustomerCode, x.ForStatement})
            .HasForeignKey(s => new { s.Code, s.AlwaysTrue});
    }
    
    public class Customer
    {
        public int Id;
        public CustomerAddress StatementAddress;
        [Column("StatementAddress_ForStatement")]
        public bool AlwaysTrue => true;
        [Column("StatementAddress_CustomerCode")]
        public string Code;
    }
    
    public class Customer
    {
        public int Id;
        public CustomerAddress StatementAddress;
        [ForeignKey("StatementAddress"), Column(Order = 1)]
        public bool AlwaysTrue => true;
        [ForeignKey("StatementAddress"), Column(Order = 0)]
        public string Code;
    }
    
    请记住,对于此选项,必须将列顺序属性设置为与
    CustomerAddress
    表中的外键所具有的属性相匹配


  • 希望这有帮助

    所以,要结束这一切-


    这在EF Core(2.1)中目前是不可能的,如果在未来的版本中添加它,还有待观察-因为目前它只支持通过单个属性映射,用Column属性标记字段并没有真正的帮助,因为它只是指定这些字段是数据库中的列名,而实际上它们不是。用外键标记单个属性对我来说似乎有点奇怪?就像根据EF core上的microsoft文档设置复合键那样,你不能这样做?如果你使用代码优先迁移,使用column属性,这些将成为列名。就ForeignKey属性而言,您能否提供一个指向Microsoft文档部分的链接,说明它不能以这种方式使用?因为就我所见,EF core支持这个属性。嘿,根本不使用迁移-以数据库优先的方式运行,因为数据库本身实际上是第三方的,所以不可编辑,否则会破坏其他系统。