Search code examples
c#entity-frameworkef-code-firstforeign-keyscomposite-key

composite key as foreign key


I am using Entity framework 4.1 in MVC 3 application. I have an entity where I have primary key consists of two columns ( composite key). And this is being used in another entity as foreign key. How to create the relationship ? In normal scnerios we use :

public class Category
{
    public string CategoryId { get; set; }
    public string Name { get; set; }

    public virtual ICollection<Product> Products { get; set; }
}

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public string CategoryId { get; set; }

    public virtual Category Category { get; set; }
} 

but what if category has two columns key ?


Solution

  • You can use either fluent API:

    public class Category
    {
        public int CategoryId1 { get; set; }
        public int CategoryId2 { get; set; }
        public string Name { get; set; }
    
        public virtual ICollection<Product> Products { get; set; }
    }
    
    public class Product
    {
        public int ProductId { get; set; }
        public string Name { get; set; }
        public int CategoryId1 { get; set; }
        public int CategoryId2 { get; set; }
    
        public virtual Category Category { get; set; }
    }
    
    public class Context : DbContext
    {
        public DbSet<Category> Categories { get; set; }
        public DbSet<Product> Products { get; set; }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
    
            modelBuilder.Entity<Category>()
                .HasKey(c => new {c.CategoryId1, c.CategoryId2});
    
            modelBuilder.Entity<Product>()
                .HasRequired(p => p.Category)
                .WithMany(c => c.Products)
                .HasForeignKey(p => new {p.CategoryId1, p.CategoryId2});
    
        }
    }
    

    Or data annotations:

    public class Category
    {
        [Key, Column(Order = 0)]
        public int CategoryId2 { get; set; }
        [Key, Column(Order = 1)]
        public int CategoryId3 { get; set; }
        public string Name { get; set; }
    
        public virtual ICollection<Product> Products { get; set; }
    }
    
    public class Product
    {
        [Key]
        public int ProductId { get; set; }
        public string Name { get; set; }
        [ForeignKey("Category"), Column(Order = 0)]
        public int CategoryId2 { get; set; }
        [ForeignKey("Category"), Column(Order = 1)]
        public int CategoryId3 { get; set; }
    
        public virtual Category Category { get; set; }
    }