Entity Framework CodeFirst many to many relationship with additional information
21,275
Solution 1
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);
}
Solution 2
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.
Related videos on Youtube
Author by
Attilah
Updated on July 09, 2022Comments
-
Attilah almost 2 years
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 ?
-
Mark Good about 13 yearsThanks for the good answer! It helped. I knew about making the navigation properties virtual, but why did you make the scalar properties virtual?
-
Ladislav Mrnka about 13 yearsIt is used for improving change tracking performance when using attached entities.
-
Mark Good about 13 yearsIs this true for properties that you don't intend to change (such as the primary key)?
-
Ladislav Mrnka about 13 years@Mark: Good question. I never thought about this. I'm not sure if all properties must be virtual to allow this.
-
one.beat.consumer over 11 years@LadislavMrnka: What do you think? stackoverflow.com/questions/13260306/…
-
aruno almost 11 yearsWhat I like about this link is that are some good examples of how to actually Perform updates once your model is in place
-
aruno almost 11 years@ladislavmrna can you explain why you needed to use fluent? Isn't this all convention based ? Similar answer doesn't use fluent : stackoverflow.com/a/7053393/16940
-
Ladislav Mrnka almost 11 years@Simon_Weaver: Relation configurations should not be necessary - default convention should handle them but configuration of composite key is necessary. If you don't use it you need to use attributes to tell EF about primary key of
ContractPart
class. -
granadaCoder over 10 yearsIs there a way to get a surrogate key on the ContractPart ( ContractPartSurrogateKey ) ?