EF Core – QueryFilter & Interception
主要参考
QueryFilter
QueryFilter 就是默认过滤, 非常适合用来做 Soft Delete
builder.HasQueryFilter(e => EF.Property<DateTimeOffset?>(e, "DateDeleted") == null);
设置这个以后, 一般的 query 语句就拿不到 deleted 的 row 了
如果想获取 deleted row 那么就需要通过 IgnoreQueryFilters 来 by pass 它.
blogs = db.Blogs
.Include(b => b.Posts)
.IgnoreQueryFilters()
.ToList();
Interception
Interception 也适合用来做 Soft Delete 或者简单的 Audit Trail
但是还有一个更简单的做法是直接 override SaveChangesAsync 方法
去 DbContext class
public override Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
foreach (var entry in ChangeTracker.Entries())
{
if (entry.State == EntityState.Added)
{ }
else if (entry.State == EntityState.Modified)
{ }
else if (entry.State == EntityState.Deleted)
{ }
var tableName = entry.Metadata.GetTableName(); foreach (var property in entry.Properties)
{
var isModified = property.IsModified;
var originalValue = property.OriginalValue;
var currentValue = property.CurrentValue;
var metadata = property.Metadata;
}
}
return base.SaveChangesAsync(cancellationToken);
}
获取 Entry 资料, 然后修改 Entry 就可以操控最终 save 的结构了. (比如把 Deleted 换成 Modified)
创建一个 Interceptor (我这里用 SaveChangesInterceptor 举例)
public class SoftDeleteInterception : SaveChangesInterceptor
{
public override ValueTask<InterceptionResult<int>> SavingChangesAsync(DbContextEventData eventData, InterceptionResult<int> result, CancellationToken cancellationToken = default)
{
var entities = eventData.Context!.ChangeTracker.Entries();
return new ValueTask<InterceptionResult<int>>(result);
}
}
注: SavingChangesAsync 是 before SQL, SavedChangesAsync 是 after success SQL, FailedChangesAsync 是 after fail SQL.
在 DbContext class register 这个 interceptor
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.AddInterceptors(new SoftDeleteInterception());
Change State in SaveChanges
看注释, 有些逻辑和平时会不同,比如 set value 时, 不会 update IsModified (但 generate 出来的语句还是有的, 我想可能 EF 最后还会再对比一次吧...懒惰去研究了)
foreach (var entry in eventData.Context!.ChangeTracker.Entries())
{
var entityType = entry.Entity.GetType();
if (entityType.FullName == "TestEFCore.Product")
{
entry.State = EntityState.Unchanged; // if change to modified then all properties will become IsModified
typeof(Product).GetProperty("Name")!.SetValue(entry.Entity, "New Value"); // current value 会 update, but IsModified 依然是 false
entry.Property("DateDeleted").CurrentValue = DateTimeOffset.Now;
entry.Property("DateDeleted").IsModified = true; // will update entry.State to modified
foreach (var p in entry.Properties)
{
var isModified = p.IsModified;
}
var state = entry.State;
}
}
Dependency Injection inside Interceptor
参考:
Ability to register IInterceptor without an IDbContextOptionsExtension
A better way of resolving EF Core interceptors with dependency injection
EF Core – QueryFilter & Interception的更多相关文章
- EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)
官方文档英文地址:https://github.com/aspnet/EntityFramework/wiki/Roadmap 历经延期和更名,新版本的实体框架终于要和大家见面了,虽然还有点害羞.请大 ...
- 一步步学习EF Core(2.事务与日志)
前言 上节我们留了一个问题,为什么EF Core中,我们加载班级,数据并不会出来 其实答案很简单,~ 因为在EF Core1.1.2 中我们在EF6.0+中用到的的延迟加载功能并没有被加入,不过在EF ...
- [转]一步步学习EF Core(2.事务与日志)
本文转自:http://www.cnblogs.com/GuZhenYin/p/6862505.html 上节我们留了一个问题,为什么EF Core中,我们加载班级,数据并不会出来 其实答案很简单,~ ...
- [转]EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)
本文转自:http://www.cnblogs.com/VolcanoCloud/p/5572408.html 官方文档英文地址:https://github.com/aspnet/EntityFra ...
- ef core 全局过滤
有些固定的条件,基本每个查询的时候需要带的条件,我们可以使用全局过滤来帮我们,这样后面的查询就不用每次都带条件了. 微软自带的:https://docs.microsoft.com/zh-cn/ef/ ...
- 万字长文,带你彻底理解EF Core5的运行机制,让你成为团队中的EF Core专家
在EF Core 5中,有很多方式可以窥察工作流程中发生的事情,并与该信息进行交互.这些功能点包括日志记录,拦截,事件处理程序和一些超酷的最新出现的调试功能.EF团队甚至从Entity Framewo ...
- EF Core 数据库迁移(Migration)
工具与环境介绍 1.开发环境为vs 2015 2.mysql EF Core支持采用 Pomelo.EntityFrameworkCore.MySql 源代码地址(https://github. ...
- Asp.net Core 通过 Ef Core 访问、管理Mysql
本文地址:http://www.cnblogs.com/likeli/p/5910524.html 环境 dotnet Core版本:1.0.0-preview2-003131 本文分为Window环 ...
- EF Core 杂记
本系列文章,将介绍本人在学习和使用EF Core的过程中的收获与心得. 或许有的地方讲的错误 欢迎大家批评指出. 1.EF Core 数据库迁移(Migration)
- MySQL官方.NET Core驱动已出,支持EF Core
千呼万唤始出来MySQL官方.NET Core驱动已出,支持EF Core. 昨天MySQL官方已经发布了.NET Core 驱动,目前还是预览版,不过功能已经可用. NuGet 地址:https:/ ...
随机推荐
- Windows 10 LTSC启用Microsoft Store的方法
新建msreg.bat文件,并编辑内容如下: ========== @echo off :: BatchGotAdmin :------------------------------------- ...
- [oeasy]python0109_tty_打字头_电传打字机_字模_点阵字库
点阵字库 回忆上次内容 上次回顾了 字符字型 的 进化过程 从 谷腾堡 活字 到 罗马正字 和 意大利斜体 罗马帝国战斗力的征服 和 基督教文化传播 使得 拉丁字符 在日耳曼语地区广泛传播 种葡萄 ...
- [oeasy]python0026_刷新时间_延迟时间_time_sleep_死循环_while_True
刷新时间 回忆上次内容 time 是一个 module import 他可以做和时间相关的事情 time.time() 得到当前时间戳 time.localtime() 得到本地时间元组 l ...
- 理解es6 Promise的resolve和reject方法
Promise.resolve() 有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用. const jsPromise = Promise.resolve ...
- QT 的 ModelView
QApplication a(argc, argv); QDirModel model; //QDirModel, 问文件目录树 QTreeView tree; QListView l ...
- VUE系列---深度解析 Vue 优化策略
在前端开发中,性能优化一直是一个重要的课题.Vue.js 提供了多种优化策略,帮助开发者构建高性能的应用.本文将深入解析以下几个优化策略: 使用 v-once.v-if 和 v-show 的区别和优化 ...
- whk随记
金刚烷,实际上是p4把磷换成碳,然后在每两个碳之间再加一个碳,氢再补齐,由于碳都是sp3杂化,所以画出来并不对称,但实际上是对称的,一氯代物只有两种,像p4o6一样,而p4o10实际上是每个磷外面再连 ...
- 【SpringSecurity】01 授权、认证、注销
[前提情要] Security学习地址: https://www.bilibili.com/video/BV1KE411i7bC 狂神的微信笔记: https://mp.weixin.qq.com/s ...
- 个人的谷歌学术主页:https://scholar.google.co.kr/citations?user=jHvm-VAAAAAJ&hl=en
主页地址: https://scholar.google.co.kr/citations?user=jHvm-VAAAAAJ&hl=en
- python3.6—opencv-python报错:Exception: Not found: 'python/cv2/py.typed'
报错: self).run_setup(setup_script=setup_script) File "/tmp/pip-build-env-zsqslesq/overlay/lib/py ...