Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework CodeFirst many to many relationship with additional information

I have the following model :

class Contract {    string ContractID{get;set;}    ICollection<Part> Parts{get;set;} }  class Part {    string PartID{get;set;}    ICollection<Contract> Contracts{get;set;} } 

the problem is that the relationship between Part and Contract also contains the following additional information :

class ContractParts {     Contract{get;set;}    Part{get;set;}    Date{get;set;} //additional info    Price{get;set;} //additional info } 

How would I write the Entity Context for this ?

like image 433
Attilah Avatar asked Mar 25 '11 14:03

Attilah


People also ask

How does Entity Framework handle many-to-many relationships?

To configure many-to-many relationship Using Data Annotations, you need to create the Join Table in the model. The Join Table BookCategory will have properties for the primary key of both the table. It will have two navigational properties one each for Book and Category class.

How do you create a foreign key relationship in code first approach?

To create Foreign Key, you need to use ForeignKey attribute with specifying the name of the property as parameter. You also need to specify the name of the table which is going to participate in relationship. I mean to say, define the foreign key table. Thanks for reading this article, hope you enjoyed it.

How do I code first in Entity Framework?

Step 1 − First, create the console application from File → New → Project… Step 2 − Select Windows from the left pane and Console Application from the template pane. Step 3 − Enter EFCodeFirstDemo as the name and select OK. Step 4 − Right-click on your project in the solution explorer and select Manage NuGet Packages…


2 Answers

In such case you must model your entities this way:

public class Contract {    public virtual string ContractId { get; set; }    public virtual ICollection<ContractPart> ContractParts { get; set; } }  public class Part {    public virtual string PartId { get;set; }    public virtual ICollection<ContractPart> ContractParts { get; set; } }  public class ContractPart {     public virtual string  ContractId { get; set; }    public virtual string PartId { get; set; }    public virtual Contract Contract { get; set; }    public virtual Part Part { get; set; }    public virtual string Date { get; set; } //additional info    public virtual decimal Price { get; set; } //additional info } 

In derived context you must define:

protected override void OnModelCreating(DbModelBuilder modelBuilder) {    modelBuilder.Entity<ContractPart>()                .HasKey(cp => new { cp.ContractId, cp.PartId });     modelBuilder.Entity<Contract>()                .HasMany(c => c.ContractParts)                .WithRequired()                .HasForeignKey(cp => cp.ContractId);     modelBuilder.Entity<Part>()                .HasMany(p => p.ContractParts)                .WithRequired()                .HasForeignKey(cp => cp.PartId);   } 
like image 132
Ladislav Mrnka Avatar answered Sep 25 '22 17:09

Ladislav Mrnka


Perhaps a better way to do is this answer? Create code first, many to many, with additional fields in association table

It doesn't require fluent APIs and also sets up the PK on join table.

like image 40
Shital Shah Avatar answered Sep 25 '22 17:09

Shital Shah