Reputation: 91
So, I have three classes
public class ParameterType
{
public ParameterType(){}
public int ParameterTypeId;
public string Type;
}
public class Parameter
{
public int ParameterId;
public string Description;
public int ParameterTypeId;
public virtual ParameterType ParameterType;
}
public class Analysis
{
public Analysis()
{
ParameterList = new List<Parameter>();
}
public int Id;
public int Number;
public string Description;
public virtual List<Parameter> ParameterList;
}
It properly maps relationship between Parameter
and ParameterType
(FK in Parameter
, if i try to insert id which doesnt exist I get an error - correct)
Now, Analysis
has set of parameters, for example if it analysis
has 5 parameters I should insert 5 records with same Number
and different parameterId
. How do I achieve that?
Also, how do I insert it with code? I've tried this:
List<Parameter> paramList = new ParamList<Parameter>
paramList.Add(new Parameter(){ParameterId = 2});
paramList.Add(new Parameter(){ParameterId = 3});
Analysis analysis = new Analysis()
analysis.ParameterList = paramList;
ctx.Add(analysis);
ctx.SaveChanges();
But all I got was 2 new records in Parameter
table and one in Analysis
WITHOUT link do Parameters
.
Should I iterate through collection and add new Analysis
record for each Parameter
with corresponding ParameterId
? (so I should add public int ParameterId
in Analysis class?)
Tried to follow http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx but it gave me AnalysisId
in Parameters
table (I did exactly way presented on the page, checked few times)
Upvotes: 0
Views: 559
Reputation: 761
Ok, I think I see the problem; however, the question is a little difficult to understand, so I apologize if I posted this as an answer when I really should have used a comment to get clarification.
Since you are wanting Analysis to have a collection of Parameters, you need to either describe that relationship using fluent as indicated by Erik Philips or add a foreign key and a navigation property to your Parameter class so that EF understands the relationship.
Your code would look something like this...notice that I have changed the name of your ID property on the Analysis class, as also suggested by Darren.
public class Parameter
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ParameterId { get; set; }
...
[ForeignKey("AnalysisId")]
public Analysis Analysis { get; set; }
public int AnalysisId { get; set; }
}
public class Analysis
{
...
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int AnalysisId { get; set; }
virtual public ICollection<Parameter> Parameters { get; set; }
}
On the other hand, if you would like to assign Parameters to more than one Analysis, then you'll need to change this method slightly and use an intermediate table because that implies a many-to-many relationship.
public class Parameter
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ParameterId { get; set; }
...
virtual public ICollection<Analysis> Analyses { get; set; }
}
public class Analysis
{
...
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int AnalysisId { get; set; }
virtual public ICollection<Parameter> Parameters { get; set; }
}
EF will map this for you; however, it will require a specifically named table with specifically named columns. I prefer to map this using fluent, which you accomplish by modifying your DbContext object. DbContext has a virtual method called OnModelCreating that gets a DbModelBuilder. You can express relationships using the fluent syntax like this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new ParameterConfiguration());
}
That goes in the class that extends DbContext. ParameterConfiguration is a class that you create that derives from EntityTypeConfiguration, like this:
public class ParameterConfiguration : EntityTypeConfiguration<Parameter>
{
public ParameterConfiguration()
{
this.HasMany(t => t.Analyses)
.WithMany(t => t.Parameters)
.Map(m => m.ToTable("ParamsForAnalyses")
.MapLeftKey("ParameterId")
.MapRightKey("AnalysisId"));
}
}
Now, create a table called "ParamsForAnalyses" and give it two columns, ParameterId and AnalysisId. EF will use that table to manage many-to-many relationships between Parameter and Analysis. Create the relationships is simple...just add a Parameter to the Parameters collection in an Analysis proxy that you've gotten from EF, or add an Analysis to a Parameter proxy, and then call SaveChanges.
(EF creates proxies based on your classes.) I'm pretty sure you can get away with just adding one side of the relationship and EF creates the other...no need to add a Parameter to an Analysis and an Analysis to a Parameter to express the relationship...just one or the other.
Upvotes: 2