提问人:Amin 提问时间:11/2/2023 更新时间:11/2/2023 访问量:70
在 EF Core 中使用计算的 IsDeleted 列进行软删除,无需手动使用 SQL 语句
Soft Delete with computed IsDeleted column in EF Core, without manually using SQL statement
问:
我有一个模型,其中包含一个属性。我想为它实现软删除。我可以简单地用来检查它是否为 null。
问题是:我想知道,是否有某种方法可以在模型中有一个计算字段,该字段未映射到数据库中的任何列。但它是通过检查 的值来评估的。
我尝试的是在模型中定义这样的属性:DeleteTime
DeleteTime
IsDeleted
DeleteTime
public bool IsDeleted { get { return DeleteTime != null; } }
然后在数据库上下文的 OnModelCreating 中:
modelBuilder.Entity<MyModelName>().HasQueryFilter(c => !c.IsDeleted);
但是在尝试将其转换为 SQL 时会抛出错误。 我阅读了类似问题的解决方案。但 我不打算通过 SQL 语句直接在数据库中创建新的计算列;正如我所说,我不希望它映射到任何现有列。 只是想知道这样的事情是否可能。
答:
1赞
Steve Py
11/2/2023
#1
查询筛选器和将表达式转换为 SQL 的任何其他 Linq 操作不能包含自定义函数或属性,因为 SQL 无法执行该代码。因此,你要么需要以一种可以直接翻译的方式编写你的过滤器,比如 Svyatoslav 的评论,要么如果你想将它们关联到一个实体或类似基 Entity 类的东西:
public abstract class SoftDeleteEntity
{
public int Id { get; protected set; }
public DateTime? DeleteTime { get; set; } = null;
public static Expresssion<Func<TEntity, bool>> IsDeletedExpr => (e) => e.DeletedTime != null;
}
假设您的实体有一个支持软删除的基类,否则可以将其直接放入实体中。
然后,当您要应用查询筛选器或 Where 子句时:
modelBuilder.Entity<MyModelName>()
.HasQueryFilter(SoftDeleteEntity.IsDeletedExpr);
如果你想让过滤器更加封装,这应该可以解决问题。
评论
0赞
Amin
11/4/2023
实际上,将其定义为表达式更接近我的意思,而不是具有自定义拦截器;因为它会涉及许多变化,这是不值得的。泰。
评论
HasQueryFilter(c => c.DeleteTime == null)