C# Entity Framework 核心 - 将子项添加到软删除的父项 OnSave 时引发错误
C# Entity Framework Core - Throw an error when child item gets added to a soft-deleted parent OnSave
我有一堆表,其中包含用于 soft-delete
功能的 DeletedAt
列。我已经实现了大部分逻辑并且一切正常,除了一个问题允许将子记录添加到软删除的父记录。当 DbContext.OnSave()
运行并发现父记录 (foreignKey
) 实际上是 soft-deleted
.
时,我想抛出一个异常
有什么方法可以在添加子元素之前注入过滤器或可以检查父 DeletedAt
字段的东西吗?
我确实没有什么想法,但有点痛苦,需要遍历子模型中的所有 foreignKeys 并检查该父对象是否设置了 DeletedAt
。
如有任何想法,我们将不胜感激。谢谢。
EF Core 可用的一个选项(在 EF6 中有点痛苦)是完全封装集合,以便 通过 parent 添加项目,从而允许您控制是否可以添加项目取决于 parent 的当前状态。
参见:https://ardalis.com/encapsulated-collections-in-entity-framework-core/
要点是限制将 Children 添加到 parent 上名为 AddChild(child)
的方法,该方法断言 parent 不是 soft-deleted .
所以我确实找到了一个解决方案,它还不错,这里是 DbContext
文件中任何感兴趣的人(在您的代码到达 DbContext.SaveChanges()
之前)的实现:
var entry = Entry(childModel);
foreach(var prop in entry.CurrentValues.Properties)
{
// Handle FKs only
if(!prop.IsForeignKey()) continue;
var fkValue = entry.CurrentValues[prop.Name];
// Handle nullable properties and skip the checks if the value is null
if(prop.IsColumnNullable() && fkValue == null) continue;
// If value is null or 0 then break
if(fkValue == null || (int)fkValue == 0)
{
throw new Exception("Must contain a value.");
}
// Get the FK
var fk = prop.GetContainingForeignKeys().FirstOrDefault();
if(fk == null)
{
throw new Exception("FK constraint is not available.");
}
// If parent is not available or deleted
var parent = Find(fk.PrincipalEntityType.ClrType, new object[]{fkValue});
if(parent == null)
{
throw new Exception($"The entered FK value ({fkValue}) is not valid.");
}
}
Find
方法实际上有一个全局过滤器,用于检查是否设置了 DeletedAt
字段。如果记录不存在,这将失败。这应该足够动态以处理 table.
中的所有 FK
我有一堆表,其中包含用于 soft-delete
功能的 DeletedAt
列。我已经实现了大部分逻辑并且一切正常,除了一个问题允许将子记录添加到软删除的父记录。当 DbContext.OnSave()
运行并发现父记录 (foreignKey
) 实际上是 soft-deleted
.
有什么方法可以在添加子元素之前注入过滤器或可以检查父 DeletedAt
字段的东西吗?
我确实没有什么想法,但有点痛苦,需要遍历子模型中的所有 foreignKeys 并检查该父对象是否设置了 DeletedAt
。
如有任何想法,我们将不胜感激。谢谢。
EF Core 可用的一个选项(在 EF6 中有点痛苦)是完全封装集合,以便 通过 parent 添加项目,从而允许您控制是否可以添加项目取决于 parent 的当前状态。
参见:https://ardalis.com/encapsulated-collections-in-entity-framework-core/
要点是限制将 Children 添加到 parent 上名为 AddChild(child)
的方法,该方法断言 parent 不是 soft-deleted .
所以我确实找到了一个解决方案,它还不错,这里是 DbContext
文件中任何感兴趣的人(在您的代码到达 DbContext.SaveChanges()
之前)的实现:
var entry = Entry(childModel);
foreach(var prop in entry.CurrentValues.Properties)
{
// Handle FKs only
if(!prop.IsForeignKey()) continue;
var fkValue = entry.CurrentValues[prop.Name];
// Handle nullable properties and skip the checks if the value is null
if(prop.IsColumnNullable() && fkValue == null) continue;
// If value is null or 0 then break
if(fkValue == null || (int)fkValue == 0)
{
throw new Exception("Must contain a value.");
}
// Get the FK
var fk = prop.GetContainingForeignKeys().FirstOrDefault();
if(fk == null)
{
throw new Exception("FK constraint is not available.");
}
// If parent is not available or deleted
var parent = Find(fk.PrincipalEntityType.ClrType, new object[]{fkValue});
if(parent == null)
{
throw new Exception($"The entered FK value ({fkValue}) is not valid.");
}
}
Find
方法实际上有一个全局过滤器,用于检查是否设置了 DeletedAt
字段。如果记录不存在,这将失败。这应该足够动态以处理 table.