Entity framework 从一对多关系实体框架中的父集合中删除子实体
我有以下数据库设置: 这些表映射如下:Entity framework 从一对多关系实体框架中的父集合中删除子实体,entity-framework,one-to-many,foreign-key-relationship,Entity Framework,One To Many,Foreign Key Relationship,我有以下数据库设置: 这些表映射如下: public class OrderMapping : EntityTypeConfiguration<Order> { public OrderMapping() { this.ToTable("Orders", "prf"); this.HasKey(o => o.OrderId); this.HasMany(o => o.OrderItems)
public class OrderMapping : EntityTypeConfiguration<Order>
{
public OrderMapping()
{
this.ToTable("Orders", "prf");
this.HasKey(o => o.OrderId);
this.HasMany(o => o.OrderItems)
.WithRequired(oi => oi.Order)
.HasForeignKey(oi => oi.OrderId);
this.HasRequired(o => o.Institution)
.WithMany()
.HasForeignKey(o => o.InstitutionId);
this.Property(o => o.IsConfirmed)
.IsRequired();
this.Ignore(o => o.Id);
}
}
public class OrderItemMapping : EntityTypeConfiguration<OrderItem>
{
public OrderItemMapping()
{
this.ToTable("OrderItems", "prf");
this.HasKey(oi => oi.OrderItemId);
this.HasRequired(oi => oi.Order)
.WithMany(oi => oi.OrderItems)
.HasForeignKey(oi => oi.OrderId);
this.HasRequired(oi => oi.Proficiency)
.WithMany()
.HasForeignKey(oi => oi.ProficiencyId);
this.HasOptional(oi => oi.Enrolment)
.WithMany()
.HasForeignKey(oi => oi.EnrolmentId);
this.HasMany(oi => oi.OrderItemSets)
.WithRequired(ois => ois.OrderItem)
.HasForeignKey(ois => ois.OrderItemId);
this.Property(oi => oi.DateCreated);
this.Ignore(oi => oi.Id);
}
}
public class OrderItemSetMapping : EntityTypeConfiguration<OrderItemSet>
{
public OrderItemSetMapping()
{
this.ToTable("OrderItemSets", "prf");
this.HasKey(ois => ois.OrderItemSetId);
this.HasRequired(ois => ois.OrderItem)
.WithMany(ois => ois.OrderItemSets)
.HasForeignKey(ois => ois.OrderItemId);
this.Property(ois => ois.NumberOfSets);
this.Property(ois => ois.Month);
}
}
我不知道我的映射有什么问题,让Entity Framework认为应该将foreignkey设置为null而不是删除行。您需要的是介于OderItem
和OrderItemSet
之间的映射。从上文提供的链接中识别和不识别关系的注意事项部分:
删除关系将删除从属对象。在EntityCollection上调用Remove方法会标记要删除的关系和从属对象
你应该考虑同一类型的关系:<代码>订单< /代码>和<代码> OrthItgs< /C> > < /P> 基本思想是,对于
OrderItemSet
模型,将OrderItem
的外键作为OrderItemSet
主键的一部分,从而创建一个复合键。在OrderItemSet
的映射中,尝试这样映射主键:
public OrderItemSetMapping()
{
...
this.HasKey(ois => new { ois.OrderItemSetId, ois.OrderItemId });
...
}
在这种情况下,请尝试使用属性创建映射:
public class OrderItemSet
{
[Key, ForeignKey("OrderItem"), Column(Order = 1)]
public <YourKeyType> OrderItemId { get; set; }
[Key, Column(Order = 2)]
public <YourKeyType> OrderItemSetId { get; set; }
...
}
公共类OrderItemSet
{
[键,外键(“订单项”),列(订单=1)]
公共OrderItemId{get;set;}
[键,列(顺序=2)]
public OrderItemSetId{get;set;}
...
}
为什么不直接删除子项:
context.OrderItemSets.Remove(orderItemSet);
context.SaveChanges();
从父级中删除子级时,可能希望将其添加到另一个父级,因此Entity Framework不适合自动删除该子级。你应该自己做。我已经按照阿本丹扎的建议解决了这个问题。首先,创建实体的键以包含外键(这将强制实体框架删除子项,因为没有外键它无法存在): 如果从父集合中删除实体,Entity Framework现在将删除该实体,但是由于OrderItemSetId是一个标识列,这会产生另一个问题,在向父集合添加新项时,Entity Framework现在希望在该列中插入值(这将引发异常)。通过在此列上指定DatabaseGenerationOption,问题将得到解决:
public OrderItemSetMapping()
{
...
this.Property(r => r.OrderItemSetId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
...
}
您看过外键上的
WillCascadeOnDelete
选项了吗?如果父实体被删除,WillCascadeOnDelete将只删除子实体。我正在从父项中删除子项,因此EF正在删除两者之间的关系。但是,由于foreignkey不可为null,因此它也应该删除子项,而不是将foreignkey设置为null。我已删除了如上所述的双重关系,但仍然得到foreignkey不能设置为null的错误。this.HasMany(o=>o.OrderItems).WithRequired(o=>o.Order).HasForeignKey(o=>o.OrderId);而this.HasMany(oi=>oi.OrderItemSets).WithRequired(oi=>oi.OrderItem).HasForeignKey(oi=>oi.OrderItemId);为什么不把我的答案标记为已接受?您基本上使用了我的答案,并添加了一些与问题中所述问题不直接相关的内容。不太好,你知道。@Abbondanza我很抱歉你有这种感觉。我在回答中确实给了你信任,但是第二部分对于问题的完整解决是绝对必要的。
public OrderItemSetMapping()
{
...
this.HasKey(ois => new { ois.OrderItemSetId, ois.OrderItemId });
...
}
public OrderItemSetMapping()
{
...
this.Property(r => r.OrderItemSetId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
...
}