实体框架6做关系错了吗?

时间:2014-06-10 18:52:13

标签: c# entity-framework entity-framework-6

所以,我有三个班级

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;


}

它正确映射ParameterParameterType之间的关系(Parameter中的FK,如果我尝试插入不存在的ID,我会收到错误 - 正确) 现在,Analysis有一组参数,例如,如果analysis有5个参数,我应该插入5条记录,其中NumberparameterId不同。我如何实现这一目标?

另外,如何将其与代码一起插入?我试过这个:

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();

但我得到的只是Parameter表中的2条新记录和Analysis中的一条没有链接的Parameters。 我是否应该遍历集合并为每个Analysis添加相应Parameter的新ParameterId条记录? (所以我应该在Analysis类中添加public int ParameterId?) 试图关注http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx,但它在AnalysisId表格中给了我Parameters(我确实在页面上显示过,检查了几次)

1 个答案:

答案 0 :(得分:2)

好的,我想我看到了问题;但是,这个问题有点难以理解,所以如果我把这个作为答案发布,我真的应该用评论来澄清一下,我很抱歉。

由于您希望Analysis具有参数集合,因此您需要使用Erik Philips指示的fluent描述该关系,或者在Parameter类中添加外键和导航属性,以便EF了解关系。 / p>

您的代码看起来像这样......请注意我已经在Analysis类中更改了您的ID属性的名称,这也是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; }
}

另一方面,如果您想将参数分配给多个Analysis,那么您需要稍微更改此方法并使用中间表,因为这意味着多对多关系。

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将为您绘制此图;但是,它需要一个具有特定命名列的特定命名表。我更喜欢使用流畅的方式映射它,您可以通过修改DbContext对象来完成。 DbContext有一个名为OnModelCreating的虚方法,它获取DbModelBuilder。您可以使用流利的语法表达关系,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new ParameterConfiguration());
}

这是扩展DbContext的类。 ParameterConfiguration是您创建的一个派生自EntityTypeConfiguration的类,如下所示:

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"));
    }
}

现在,创建一个名为“ParamsForAnalyses”的表,并为其提供两列,ParameterId和AnalysisId。 EF将使用该表来管理参数和分析之间的多对多关系。创建关系很简单...只需将参数添加到您从EF获得的Analysis代理中的Parameters集合,或者将Analysis添加到Parameter代理,然后调用SaveChanges。

(EF根据你的类创建代理。)我很确定你只需添加关系的一面就可以逃脱,EF会创建另一面......不需要在Analysis和Analysis中添加参数参数表达关系...只是一个或另一个。