Mapping foreign key to non primary surrogate key column in EF code first

余生长醉 提交于 2021-01-02 06:16:12

问题


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

relationship between B and C is troubling me .I dont want to include BName as foreign key in Class C

Error : The number of properties in the Dependent and Principal Roles in a relationship constraint must be identical

I understand the error but I want to point to C class only by Bid ,how I can achieve it without disturbing the relationship between A and B.


回答1:


This question is tagged for EF6. But if you find this searching for EF Core. Can use Alternate Keys.

From link:

Alternate keys can be used as the target of a relationship.

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:


As far as I understand it is not possible to do it in EF code first with either attributes or fluent api:

  • Entity Framework 6.1.3 Mapping Foreign key to non primary key
  • Entity Framework 5.0 composite foreign key to non primary key - is it possible?
  • Entity Framework Code first mapping without foreign key

But I can propose you to remodel your solution a bit - don't create a primary key on B(BName, Aid) - make it an unique index - 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; } 
}

The index will give you the same performance benefits for querying as the primary key (though with a bit of additional overhead to support the primary surrogate index over the Bid column).

Also, recommended reading - Surrogate vs. natural/business keys.



来源:https://stackoverflow.com/questions/38029313/mapping-foreign-key-to-non-primary-surrogate-key-column-in-ef-code-first

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!