实体框架6处理关系错误

本文关键字:关系 错误 处理 框架 实体 | 更新日期: 2023-09-27 18:07:55

我有三个类

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条具有相同Number和不同parameterId的记录。我该怎么做呢?

还有,我如何用代码插入它?我试过了:

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

但是所有我得到的是2个新记录在Parameter表和一个在Analysis没有链接做Parameters。我应该通过集合迭代并为每个Parameter添加新的Analysis记录与相应的ParameterId吗?(所以我应该在分析类添加public int ParameterId ?)试图遵循http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx,但它给了我AnalysisIdParameters表(我做了正确的方式呈现在页面上,检查了几次)

实体框架6处理关系错误

好的,我想我看到问题了;然而,这个问题有点难以理解,所以我很抱歉我把这篇文章作为一个答案,而我真的应该用评论来澄清。

因为你想让Analysis有一个Parameters的集合,你需要像Erik Philips指出的那样使用fluent来描述这种关系,或者在Parameter类中添加一个外键和一个导航属性,以便EF理解这种关系。

你的代码看起来像这样…请注意,我已经更改了分析类上的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; }
}

另一方面,如果您希望将Parameters分配给多个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将为您映射这个;但是,它需要一个特定命名的表和特定命名的列。我更喜欢使用fluent来映射,这可以通过修改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将使用这个表来管理Parameter和Analysis之间的多对多关系。建立关系很简单……只需在您从EF获得的分析代理中的参数集合中添加一个参数,或者在参数代理中添加一个分析,然后调用SaveChanges。

(EF基于你的类创建代理。)我很确定你可以只增加关系的一面,而EF创造了另一面……不需要在分析中添加参数,也不需要在参数中添加分析来表示关系…不选其一