更新实体时,在实体方法中删除了多个子集合的情况下,我无法将更改保存到数据库中。
我从RemoveSpecificMiddleLvlEntities
实体调用HighLvlEntity
方法。一些孩子被删除。从EfRepository
通过Update方法进行更新时,引发以下错误。
我是否必须通过Delete方法手动收集集合中的所有子级?
我认为我真的不了解基本的Entity Framework 6概念之一吗?想要让我知道哪些实体不在任何存储库或服务中委派了哪些实体。
谢谢。
错误:System.InvalidOperationException:“操作失败: 无法更改关系,因为其中一个或多个 外键属性不可为空。当对 关系时,相关外键属性设置为空值。 如果外键不支持空值,则建立新关系 必须定义,必须为外键属性分配另一个 非null值,否则必须删除不相关的对象。”
我的简化实体:
public class Base
{
public Guid Id { get; set; }
public Base()
{
Id = Guid.NewGuid();
}
}
public class HighLvlEntity : Base
{
public HighLvlEntity(string name)
{
Name = name;
}
public string Name { get; set; }
public ICollection<MiddleLvlEntity> middleLvlEntities { get; set; } = new List<MiddleLvlEntity>();
public void RemoveSpecificMiddleLvlEntities(ICollection<MiddleLvlEntity> middleLvlEntitiesOfCriteria)
{
foreach (var MiddleLvlEntity in middleLvlEntitiesOfCriteria)
{
var foundmiddleLvlEntity = middleLvlEntities.Where(p => p.Testcriteria == MiddleLvlEntity.Testcriteria).First();
middleLvlEntities.Remove(foundmiddleLvlEntity);
{
}
}
}
}
public class MiddleLvlEntity : Base
{
public MiddleLvlEntity(string testcriteria)
{
Testcriteria = testcriteria;
}
public ICollection<LowLvlTwo> LowLvlTwos { get; set; } = new List<LowLvlTwo>();
public ICollection<LowLvlOne> LowLvlOnes { get; set; } = new List<LowLvlOne>();
public string Testcriteria { get; set; }
public HighLvlEntity HighLvlEntity { get; set; }
public Guid HighlvlEntityId { get; set; }
}
public class LowLvlOne : Base
{
public LowLvlOne(DateTime date)
{
Date = date;
}
public DateTime Date { get; set; }
public Guid middleLvlEntityId { get; set; }
public MiddleLvlEntity MiddleLvlEntity { get; set; }
}
public class LowLvlTwo : Base
{
public LowLvlTwo(DateTime date)
{
Date = date;
}
public DateTime Date { get; set; }
public Guid middleLvlEntityId { get; set; }
public MiddleLvlEntity MiddleLvlEntity { get; set; }
}
EfRepository:
public class EfRepository<T> : IRepository<T> where T : Base
{
protected readonly Context _dbContext;
public EfRepository(Context dbContext)
{
_dbContext = dbContext;
}
public void Update(T entity)
{
_dbContext.Entry(entity).State = EntitieState.Modified;
_dbContext.SaveChanges();
}
public void Delete(T entity)
{
_dbContext.Set<T>().Remove(entity);
_dbContext.SaveChanges();
}
}
更新: This seems to be same problem。 然后我的问题是,我到底该如何构建它能正常工作的应用程序。我有一个包含实体,接口和服务的核心项目。具有实现并连接到实体框架的基础结构项目。因此,我在Core项目中的实体不了解dbcontext和如何从子集合中删除项目。我是否必须摆脱这种想法,而是要在实体本身中实现业务逻辑,以便在核心项目中使用服务接口并在基础结构项目中使用服务实现?
答案 0 :(得分:0)
不幸的是,当人们想要正确处理所谓的孤立记录时,对于EF6来说,似乎(大多数)不可能完全不了解实体。
How to remove child one to many related records in EF code first database?
那么,还有哪些选择呢?
显然不是您想要的,但是如果我们
它可能不会像现在看起来那样糟糕
类似https://stackoverflow.com/a/42048505/3745022
或者尝试从identifying relationships中获得最大收益-对他们来说,孤儿删除是可行的。
除非确实需要删除这些实体(域限制,数据库大小/性能,GDPR ...),否则您可以将它们标记为已删除或将它们添加到某些DeletedParent
中。
嗯,我知道这可能不可行,这会使系统的某些方面变得更加复杂且容易出错,但是在许多情况下,不删除实体会非常有利(能够回滚操作,生成历史数据等)
EF Core似乎支持正确的orphan removal。
尽管您无法使用{.3} {.3}},但仍可以尝试EF Core 2.2,因为它也应该支持孤立删除。
是的,EF和EF Core之间存在一些差异,但是对于一个似乎处于早期阶段的项目而言,它们并不是无法克服的。