【问题标题】:Mapping foreign key to non primary surrogate key column in EF code first首先将外键映射到 EF 代码中的非主代理键列
【发布时间】:2016-10-28 00:18:24
【问题描述】:
public class A    
{   
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public virtual int Aid { get; set; }    

    public virtual ICollection<B> B { get; set; }    
}


public class B
{    
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]     
    public virtual int Bid { get; set; }

    [Key]
    [Column(Order = 0)]
    [Required]           
    Public virtual string BName {get ; set}

    [Key]
    [Column(Order = 1)]
    [Required]      
    public virtual int Aid { get; set; }

    [ForeignKey("Aid")]
    public virtual  A A { get; set; }

    public virtual ICollection<C> C { get; set; }    
}


public class C
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]     
    public virtual int Cid { get; set; }

    [Key]
    [Column(Order = 0)]
    [Required]    
    Public virtual string CName {get ; set}    

    [Key]
    [Column(Order = 1)]
    [Required]          
    public virtual int Bid { get; set; }

     [ForeignKey("Bid")]
     public virtual  B B { get; set; } 
}

B 和 C 之间的关系让我很困扰。我不想在 C 类中包含 BName 作为外键

错误:从属和主要角色中的属性数量 在关系约束中必须相同

我理解错误,但我只想通过 Bid 指向 C 类,我如何在不干扰 A 和 B 之间的关系的情况下实现它。

【问题讨论】:

    标签: c# entity-framework ef-code-first foreign-keys entity-framework-6


    【解决方案1】:

    此问题已标记为 EF6。但是,如果您在搜索 EF Core 时发现此内容。可以使用Alternate Keys

    来自链接:

    备用键可用作关系的目标。

    class MyContext : DbContext
    {
        public DbSet<Blog> Blogs { get; set; }
        public DbSet<Post> Posts { get; set; }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Post>()
                .HasOne(p => p.Blog)
                .WithMany(b => b.Posts)
                .HasForeignKey(p => p.BlogUrl)
                .HasPrincipalKey(b => b.Url);
        }
    }
    
    public class Blog
    {
        public int BlogId { get; set; }
        public string Url { get; set; }
    
        public List<Post> Posts { get; set; }
    }
    
    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
    
        public string BlogUrl { get; set; }
        public Blog Blog { get; set; }
    }
    

    【讨论】:

      【解决方案2】:

      据我了解,不可能首先在 EF 代码中使用属性或流利的 api:

      但我可以建议您稍微改造一下您的解决方案 - 不要在 B(BName, Aid) 上创建主键 - 使其成为唯一索引 - Unique Key constraints for multiple columns in Entity Framework

      public class B
      {    
          [Key]
          [DatabaseGenerated(DatabaseGeneratedOption.Identity)]     
          public virtual int Bid { get; set; }
      
          [Index("IX_B_Name_Aid", 1, IsUnique = true)]
          [Required]           
          Public virtual string BName {get ; set}
      
          [Index("IX_B_Name_Aid", 2, IsUnique = true)]
          [Required]      
          public virtual int Aid { get; set; }
      
          [ForeignKey("Aid")]
          public virtual  A A { get; set; }
      
          public virtual ICollection<C> C { get; set; }    
      }
      
      
      public class C
      {
          [DatabaseGenerated(DatabaseGeneratedOption.Identity)]     
          public virtual int Cid { get; set; }
      
          [Key]
          [Column(Order = 0)]
          [Required]    
          Public virtual string CName {get ; set}    
      
          [Key]
          [Column(Order = 1)]
          [Required]          
          public virtual int Bid { get; set; }
      
          [ForeignKey("Bid")]
          public virtual  B B { get; set; } 
      }
      

      索引将为您提供与主键相同的查询性能优势(尽管在Bid 列上支持主surrogate 索引会产生一些额外开销)。

      另外,推荐阅读-Surrogate vs. natural/business keys

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-10-26
        • 2020-04-07
        • 2023-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多