[英]multiple added entities may have the same primary key on database seed
假设我使用实体框架6为asp.net mvc 5应用程序提供了以下模型结构
class Athlete {
int AthleteID {get; set;}
List<YearsAsAthlete> YearsAsAthlete {get;set;}
}
class YearsAsAthlete {
int YearsAsAthleteID {get;set;}
int AthleteID {get;set;}
[ForeignKey("AthleteID")]
Athlete Athlete {get;set;}
List<ContractRevenue> ContractRevenue {get;set;}
List<AdvertisementRevenue> AdvertisementRevenue {get;set;}
}
class ContractRevenue {
int ContractRevenueID {get;set;}
int YearsAsAthleteID {get;set;}
[ForeignKey("YearsAsAthleteID")]
YearsAsAthlete YearsAsAthlete {get;set;}
List<RevenueAmounts> RevenueAmounts {get;set;}
}
class AdvertisementRevenue {get;set;}
int AdvertisementRevenueID {get;set;}
int YearsAsAthleteID {get;set;}
[ForeignKey("YearsAsAthleteID")]
YearsAsAthlete YearsAsAthlete {get;set;}
List<RevenueAmounts> RevenueAmounts {get;set;}
}
class RevenueAmounts {
int RevenueAmountsID {get;set;}
int AmountPaid {get;set;}
date DateOfPayment {get;set;}
}
当我这样的时候,这些模型工作得很好,他们有关系,一切都很美味,就像一个热巧克力圣代。 当我运行它时,数据库创建这些表,RevenueAmounts表为ContracRevenue和AdvertisementRevenue获取2个自动生成的外键列。
但是,我不想要这些,因为它们的命名奇怪(ContractRevenue_ContractRevenueID),我需要一些方法来访问我的post控制器方法中的foreginkey id属性,以添加与正确的收入类型相关的新值。
当我将RevenueAmounts模型更改为以下内容时:
class RevenueAmounts {
int RevenueAmountsID {get;set;}
int AmountPaid {get;set;}
date DateOfPayment {get;set;}
// ***NOTE adding foreign keys here
int ContractRevenueID {get;set;}
[ForeginKey("ContractRevenueID")]
ContractRevenue ContractRevenue {get;set;}
int AdvertisementRevenueID {get;set;}
[ForeignKey("AdvertisementRevenueID")]
AdvertisementRevenue AdvertisementRevenue {get;set;}
}
我开始得到一个例外:
[SqlException(0x80131904):在表'AdvertisementRevenue'上引入FOREIGN KEY约束'FK_dbo.AdvertisementRevenue_dbo.YearsAsAthlete_YearsAsAthleteID'可能会导致循环或多个级联路径。 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。
** 编辑 **
我已经使用流畅的API关闭了级联删除功能但是现在我得到了一个不同的例外:
无法确定'GIP.DAL.ContractRevenue_RevenueAmounts'关系的主要结尾。 多个添加的实体可以具有相同的主键。
顺便说一句,当我试图将一堆信息播种到数据库中然后在底部执行context.SaveChanges()
时(仅在结束时执行一次context.SaveChanges()
,抛出异常
在您的编辑中,您提到“多个添加的实体可能具有相同的主键”。 错误。 在不知道你在这里做什么的所有细节的情况下,听起来你正在创建一个与实体的关系 - 在上下文中有两个具有相同ID的实体。 这些可能是尚未保存的新实体,它们从数据库中获取自动生成的ID。 如果关系基于ID,则存在一些歧义,因为实体框架无法确定关系实际指向哪个新实体 - 它们都具有关系所指向的ID。
有两种可能的修复方法。
为实体在上下文中创建时生成临时唯一标识符。 当实体被保存时,实体框架将丢弃它,但直到那时,它可以使用它来告诉一个新实体与另一个实体不同。 我过去曾为此目的使用过负整数。
不要使用ID创建关系,而是使用实体引用创建关系。 如果实体框架具有对实体的直接引用,则它不需要经历基于非唯一标识符来标识实体的过程,并且不应该具有该问题。
发生这种情况是因为在启用Cascade删除时,Entity Framework无法确定关系中的哪个对象是父对象。
你在使用Code First吗? 生成迁移后,您将在表声明中看到级联删除选项。 如果将其设置为false,则应解决此问题。
但是,更大的问题是您正在创建不实现聚合根的对象关系,这通常会避免此问题。
我有同样的问题但在我的情况下有另一种解决方案。 在一个循环中,我为每个父母添加了父母,我正在添加孩子。 父母和孩子之间有关系。 当然我使用FK作为虚拟参考列,但问题仍然存在。
foreach (var parent in parents)
{
var id = parent.Id;
var parentEntity = new Parent();
this.Context.Set<Parent>().Add(parentEntity);
parentEntity.CreatedOn = DateTime.UtcNow;
...
foreach (var child in parents[id].Children)
{
var childEntity = new Child();
//this.Context.Set<Child>().Add(childEntity);
parent.Children.Add(childEntity);
childEntity.CreatedOn = DateTime.UtcNow;
...
}
}
我必须注释掉将子实体添加到EF上下文的行,并修复了问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.