关系处于“已删除”状态

本文关键字:已删除 状态 删除 关系 | 更新日期: 2023-09-27 18:24:45

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

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

内部异常是:

"User_Availability"AssociationSet中的关系处于"已删除"状态。给定多重性约束,相应的"User_Availability_Target"也必须处于"Deleted"状态。

用户看起来像这样:

....
ICollection<Availability> 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来删除项,但我觉得我的代码不会那么干净。有没有办法通过清除集合来实现这一点?

关系处于“已删除”状态

我所知道的使其工作的唯一方法是将关系定义为标识关系。需要将从AvailabilityUser的外键作为外键引入到您的模型中。。。

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

并将其作为主密钥的一部分:

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

您可以扩展映射以包括此外键(只是为了明确起见,这不是必需的,因为EF会按照惯例识别它):

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

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

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

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

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

在清除可用性集合中的每个项目之前,请对其执行此操作。您不需要为此"标识关系"。

如果有人在使用SQLite时遇到同样的问题:

不幸的是,接受的答案不适用于SQLite,因为SQLite不支持复合键的自动递增。

您也可以覆盖数据库上下文中的SaveChanges()方法来删除子项:

//// Long Version
//var localChilds = this.SubCategories.Local.ToList();
//var deletedChilds = localChilds.Where(w => w.Category == null).ToList();
//foreach(var child in deletedChilds) {
//   this.SubCategories.Remove(child);
//}
// Short in LINQ
this.SubCategories.Local
    .Where(w => w.Category == null).ToList()
    .ForEach(fe => this.SubCategories.Remove(fe));
#endregion

看看这个伟大的博客文章作为我的来源(不幸的是用德语写的)。