多个添加的实体可能在数据库种子上具有相同的主键

假设我使用entity framework6为asp.net mvc 5应用程序提供了以下模型结构

class Athlete { int AthleteID {get; set;} List YearsAsAthlete {get;set;} } class YearsAsAthlete { int YearsAsAthleteID {get;set;} int AthleteID {get;set;} [ForeignKey("AthleteID")] Athlete Athlete {get;set;} List ContractRevenue {get;set;} List AdvertisementRevenue {get;set;} } class ContractRevenue { int ContractRevenueID {get;set;} int YearsAsAthleteID {get;set;} [ForeignKey("YearsAsAthleteID")] YearsAsAthlete YearsAsAthlete {get;set;} List RevenueAmounts {get;set;} } class AdvertisementRevenue {get;set;} int AdvertisementRevenueID {get;set;} int YearsAsAthleteID {get;set;} [ForeignKey("YearsAsAthleteID")] YearsAsAthlete YearsAsAthlete {get;set;} List 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关闭了级联删除function但是现在我得到了一个不同的例外:

无法确定’GIP.DAL.ContractRevenue_RevenueAmounts’关系的主要结尾。 多个添加的实体可以具有相同的主键。

顺便说一下,当我试图将一堆信息播种到数据库中然后在底部执行context.SaveChanges()时(仅在最后执行一次context.SaveChanges() ,抛出了exception

在您的编辑中,您提到“多个添加的实体可能具有相同的主键”。 错误。 在不知道你在这里做什么的所有细节的情况下,听起来你正在创建一个与实体的关系 – 在上下文中有两个具有相同ID的实体。 这些可能是尚未保存的新实体,它们从数据库中获取自动生成的ID。 如果关系基于ID,则存在一些歧义,因为entity framework无法确定关系实际指向哪个新实体 – 它们都具有关系指向的ID。

有两种可能的修复方法。

  1. 为实体在上下文中创建时生成临时唯一标识符。 当实体被保存时,entity framework将丢弃它,但直到那时,它可以使用它来告诉一个新实体与另一个实体。 我过去曾为此目的使用过负整数。

  2. 不要使用ID创建关系,而是使用实体引用创建关系。 如果entity framework直接引用该实体,则它不需要经历基于非唯一标识符识别实体的过程,并且不应该具有此问题。

发生这种情况是因为在启用Cascade删除时,Entity Framework无法确定关系中的哪个对象是父对象。

你在使用Code First吗? 生成迁移后,您将在表声明中看到级联删除选项。 如果将其设置为false,则应解决此问题。

但是,更大的问题是您正在创建不实现聚合根的对象关系,这通常会避免此问题。

我有同样的问题但在我的情况下有另一种解决方案。 在一个循环中,我为每个父母添加父母,我正在添加孩子。 父母和孩子之间有关系。 当然我使用FK作为虚拟参考列,但问题仍然存在。

 foreach (var parent in parents) { var id = parent.Id; var parentEntity = new Parent(); this.Context.Set().Add(parentEntity); parentEntity.CreatedOn = DateTime.UtcNow; ... foreach (var child in parents[id].Children) { var childEntity = new Child(); //this.Context.Set().Add(childEntity); parent.Children.Add(childEntity); childEntity.CreatedOn = DateTime.UtcNow; ... } } 

我不得不注释掉将子实体添加到EF上下文的行,并解决了这个问题。