Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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 ?

like image 993
DotnetSparrow Avatar asked Mar 25 '11 18:03

DotnetSparrow


People also ask

Can composite key be used as foreign 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.

Does MySQL support composite 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.

Can a composite key be a primary key?

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.


2 Answers

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; } } 
like image 82
Ladislav Mrnka Avatar answered Oct 07 '22 02:10

Ladislav Mrnka


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; } } 
like image 24
Christophe Avatar answered Oct 07 '22 02:10

Christophe