加载实体时违反多重约束错误
Multiplicity constraint violated Error while loading entity
我看到这个问题被问了很多次,但每个问题都有自己的情况,我找不到解决方案。
I wanted to add a table that holds a survey data, and each SURVEY
belongs to a SITE
.
我尝试添加一个 child table Site_Survey
这样如果形成 One-to-Zero_or_One 与现有 table [=18] 的关系=].
我使用 EF-6,代码优先,使用 FluentApi 进行映射。以下是我如何定义实体
Site_Survey
public class Site_Survey
{
// Scalar Properties
public int site_survey_id { get; set; }
// ..other properties removed for brevity
// Navigation Properties
public virtual Site_Report Site_Report { get; set; }
}
Site_Report
public class Site_Report
{
public Site_Report()
{
this.Report_Assets = new HashSet<Report_Asset>();
this.Site_Survey = new Site_Survey();
}
// Scalar Properties
public int site_report_id { get; set; }
// ..other properties removed for brevity
// Navigation Properties
// Site_Report one-to-zero_or_one Site_Survey
public virtual Site_Survey Site_Survey { get; set; }
}
映射
public class Site_SurveyMap : EntityTypeConfiguration<Site_Survey>
{
public Site_SurveyMap()
{
HasKey(x => x.site_survey_id);
}
}
public class Site_ReportMap : EntityTypeConfiguration<Site_Report>
{
public Site_ReportMap()
{
HasKey(one => one.site_report_id);
// mapping for Site_Report one-to-zero_or_one Site_Survey
HasOptional(o => o.Site_Survey) // Mark Site_Survey property optional in Site_Report entity
.WithRequired(o => o.Site_Report) // Mark Site_Report property as required in Site_Survey entity.
.WillCascadeOnDelete(true); // i.e. Cannot save Site_Survey without Site_Report
}
}
我在 Site_Report 构造函数中初始化 Site_Survey 以便每个新的 Site_Report 最多有一个调查。对于在调查中没有记录的旧现有网站 table 我正在添加代码逻辑并在必要时填充它们。
问题
从 DbContext 加载 Site_Survey
object 时,我成功获得了正确的调查记录
Site_Survey model = ctx.Site_Survey.Where(i => i.site_survey_id == id).FirstOrDefault();
但是如果我尝试在上下文中包含 Site_Report 实体,它会抛出错误。
Site_Survey model = ctx.Site_Survey.Include(i => i.Site_Report).Where(i => i.site_survey_id == id).FirstOrDefault();
反之亦然,如果尝试加载 Site_Report 并包含 Site_Survey。
错误
"Multiplicity constraint violated. The role 'Site_Report_Site_Survey_Target' of the relationship 'StevensCalcertPortal.DBAccessLayer.Site_Report_Site_Survey' has multiplicity 1 or 0..1."
事实上它实际上是 1-0..1 关系,我做错了什么?
在阅读这篇文章的帮助下 Entity framework and Table splitting with Code First。以下更改实际上解决了我的问题。
保持 Site_Report
构造函数不变,并使用单独的静态方法 CreateEntity()
生成对象。还将构造函数的可见性更改为受保护,以强制在代码中需要 new Site_Report();
的地方使用静态方法。
public class Site_Report
{
public static Site_Report CreateEntity()
{
return new Site_Report()
{
Site_Survey = new Site_Survey()
};
}
protected Site_Report()
{
this.Report_Assets = new HashSet<Report_Asset>();
// this.Site_Survey = new Site_Survey();
}
}
如果您在构造函数 this.Site_Survey = new Site_Survey();
中初始化 Site_Survey,基本上会发生错误。
在向数据库发出查询后,在 EF 内部构造 Site_Report
的实例时,它得到的 Site_Survey
已经填充了 ID 0 并且 EF 抱怨,因为它得到的 ID 与数据库,那么当关系为 1:1 时,EF 认为 Site_Report
指的是两个不同的 Site_Survey
(它们应该共享相同的 ID)。
我看到这个问题被问了很多次,但每个问题都有自己的情况,我找不到解决方案。
I wanted to add a table that holds a survey data, and each
SURVEY
belongs to aSITE
.
我尝试添加一个 child table Site_Survey
这样如果形成 One-to-Zero_or_One 与现有 table [=18] 的关系=].
我使用 EF-6,代码优先,使用 FluentApi 进行映射。以下是我如何定义实体
Site_Survey
public class Site_Survey
{
// Scalar Properties
public int site_survey_id { get; set; }
// ..other properties removed for brevity
// Navigation Properties
public virtual Site_Report Site_Report { get; set; }
}
Site_Report
public class Site_Report
{
public Site_Report()
{
this.Report_Assets = new HashSet<Report_Asset>();
this.Site_Survey = new Site_Survey();
}
// Scalar Properties
public int site_report_id { get; set; }
// ..other properties removed for brevity
// Navigation Properties
// Site_Report one-to-zero_or_one Site_Survey
public virtual Site_Survey Site_Survey { get; set; }
}
映射
public class Site_SurveyMap : EntityTypeConfiguration<Site_Survey>
{
public Site_SurveyMap()
{
HasKey(x => x.site_survey_id);
}
}
public class Site_ReportMap : EntityTypeConfiguration<Site_Report>
{
public Site_ReportMap()
{
HasKey(one => one.site_report_id);
// mapping for Site_Report one-to-zero_or_one Site_Survey
HasOptional(o => o.Site_Survey) // Mark Site_Survey property optional in Site_Report entity
.WithRequired(o => o.Site_Report) // Mark Site_Report property as required in Site_Survey entity.
.WillCascadeOnDelete(true); // i.e. Cannot save Site_Survey without Site_Report
}
}
我在 Site_Report 构造函数中初始化 Site_Survey 以便每个新的 Site_Report 最多有一个调查。对于在调查中没有记录的旧现有网站 table 我正在添加代码逻辑并在必要时填充它们。
问题
从 DbContext 加载 Site_Survey
object 时,我成功获得了正确的调查记录
Site_Survey model = ctx.Site_Survey.Where(i => i.site_survey_id == id).FirstOrDefault();
但是如果我尝试在上下文中包含 Site_Report 实体,它会抛出错误。
Site_Survey model = ctx.Site_Survey.Include(i => i.Site_Report).Where(i => i.site_survey_id == id).FirstOrDefault();
反之亦然,如果尝试加载 Site_Report 并包含 Site_Survey。
错误
"Multiplicity constraint violated. The role 'Site_Report_Site_Survey_Target' of the relationship 'StevensCalcertPortal.DBAccessLayer.Site_Report_Site_Survey' has multiplicity 1 or 0..1."
事实上它实际上是 1-0..1 关系,我做错了什么?
在阅读这篇文章的帮助下 Entity framework and Table splitting with Code First。以下更改实际上解决了我的问题。
保持 Site_Report
构造函数不变,并使用单独的静态方法 CreateEntity()
生成对象。还将构造函数的可见性更改为受保护,以强制在代码中需要 new Site_Report();
的地方使用静态方法。
public class Site_Report
{
public static Site_Report CreateEntity()
{
return new Site_Report()
{
Site_Survey = new Site_Survey()
};
}
protected Site_Report()
{
this.Report_Assets = new HashSet<Report_Asset>();
// this.Site_Survey = new Site_Survey();
}
}
如果您在构造函数 this.Site_Survey = new Site_Survey();
中初始化 Site_Survey,基本上会发生错误。
在向数据库发出查询后,在 EF 内部构造 Site_Report
的实例时,它得到的 Site_Survey
已经填充了 ID 0 并且 EF 抱怨,因为它得到的 ID 与数据库,那么当关系为 1:1 时,EF 认为 Site_Report
指的是两个不同的 Site_Survey
(它们应该共享相同的 ID)。