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 ?
A composite key specifies multiple columns for a primary-key or foreign-key constraint. The next example creates two tables. The first table has a composite key that acts as a primary key, and the second table has a composite key that acts as a foreign key.
MySQL supports foreign keys, which permit cross-referencing related data across tables, and foreign key constraints, which help keep the related data consistent.
Composite Key Declaration When over one column or field in a table are combined to achieve the task of uniquely identifying row values, then that composite key can be either a primary or a candidate key of that table.
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; } }
I believe the easiest way is to use Data Annotation on the Navigation property like this: [ForeignKey("CategoryId1, CategoryId2")]
public class Category { [Key, Column(Order = 0)] public int CategoryId1 { get; set; } [Key, Column(Order = 1)] public int CategoryId2 { 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; } public int CategoryId1 { get; set; } public int CategoryId2 { get; set; } [ForeignKey("CategoryId1, CategoryId2")] public virtual Category Category { get; set; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With