关系处于已删除状态

当我试图清除一个集合(调用.Clear )时,我得到以下exception:

保存不公开其关系的外键属性的实体时发生错误。 EntityEntries属性将返回null,因为无法将单个实体标识为exception的来源。 通过在实体类型中公开外键属性,可以更轻松地在保存时处理exception。 有关详细信息,请参阅InnerException。

内在的例外是:

来自’User_Availability’AssociationSet的关系处于’已删除’状态。 给定多重约束,相应的’User_Availability_Target’也必须处于’已删除’状态。

用户看起来像这样:

 .... ICollection Availability { get; set; } 

可用性如下所示:

 int ID { get; set; } User User { get; set; } DateTime Start { get; set; DateTime End { get; set; } 

配置如下:

 HasMany(x => x.Availability).WithRequired(x => x.User); HasRequired(x => x.User).WithMany(x => x.Availability); 

导致问题的代码是:

 user.Availability.Clear(); 

我已经看过其他替代方法,例如使用DbSet删除项目,但我觉得我的代码不会那么干净。 有没有办法通过清除集合来实现这一目标?

我知道使其发挥作用的唯一方法是将关系定义为识别关系 。 它需要将Availability中的外键作为外键引入到您的模型中…

 public int ID { get; set; } public int UserID { get; set; } public User User { get; set; } 

…并使其成为主键的一部分:

 modelBuilder.Entity() .HasKey(a => new { a.ID, a.UserID }); 

您可以扩展映射以包含此外键(只是为了显式,它不是必需的,因为EF会按惯例识别它):

 modelBuilder.Entity() .HasRequired(a => a.User) .WithMany(u => u.Availability) .HasForeignKey(a => a.UserID); 

(顺便说一句:您只需要从一方配置关系。在您的问题中不需要同时具有这两种映射。)

现在,您可以使用user.Availability.Clear();清除集合user.Availability.Clear(); 并且Availability实体将从数据库中删除。

有一个技巧。 您可以在不使用特殊DbSet的情况下删除实体:

 (this.dataContext as IObjectContextAdapter).ObjectContext.DeleteObject(entity); 

在清除之前,对可用性集合中的每个项执行此操作。 您不需要以这种方式“识别关系”。