繁体   English   中英

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

[英]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。

有两种可能的修复方法。

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

  2. 不要使用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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM