主要参考

Global Query Filters

Interceptors

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的更多相关文章

  1. EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)

    官方文档英文地址:https://github.com/aspnet/EntityFramework/wiki/Roadmap 历经延期和更名,新版本的实体框架终于要和大家见面了,虽然还有点害羞.请大 ...

  2. 一步步学习EF Core(2.事务与日志)

    前言 上节我们留了一个问题,为什么EF Core中,我们加载班级,数据并不会出来 其实答案很简单,~ 因为在EF Core1.1.2 中我们在EF6.0+中用到的的延迟加载功能并没有被加入,不过在EF ...

  3. [转]一步步学习EF Core(2.事务与日志)

    本文转自:http://www.cnblogs.com/GuZhenYin/p/6862505.html 上节我们留了一个问题,为什么EF Core中,我们加载班级,数据并不会出来 其实答案很简单,~ ...

  4. [转]EntityFramework Core技术线路(EF7已经更名为EF Core,并于2016年6月底发布)

    本文转自:http://www.cnblogs.com/VolcanoCloud/p/5572408.html 官方文档英文地址:https://github.com/aspnet/EntityFra ...

  5. ef core 全局过滤

    有些固定的条件,基本每个查询的时候需要带的条件,我们可以使用全局过滤来帮我们,这样后面的查询就不用每次都带条件了. 微软自带的:https://docs.microsoft.com/zh-cn/ef/ ...

  6. 万字长文,带你彻底理解EF Core5的运行机制,让你成为团队中的EF Core专家

    在EF Core 5中,有很多方式可以窥察工作流程中发生的事情,并与该信息进行交互.这些功能点包括日志记录,拦截,事件处理程序和一些超酷的最新出现的调试功能.EF团队甚至从Entity Framewo ...

  7. EF Core 数据库迁移(Migration)

    工具与环境介绍 1.开发环境为vs 2015 2.mysql EF Core支持采用  Pomelo.EntityFrameworkCore.MySql   源代码地址(https://github. ...

  8. Asp.net Core 通过 Ef Core 访问、管理Mysql

    本文地址:http://www.cnblogs.com/likeli/p/5910524.html 环境 dotnet Core版本:1.0.0-preview2-003131 本文分为Window环 ...

  9. EF Core 杂记

    本系列文章,将介绍本人在学习和使用EF Core的过程中的收获与心得. 或许有的地方讲的错误 欢迎大家批评指出. 1.EF Core 数据库迁移(Migration)

  10. MySQL官方.NET Core驱动已出,支持EF Core

    千呼万唤始出来MySQL官方.NET Core驱动已出,支持EF Core. 昨天MySQL官方已经发布了.NET Core 驱动,目前还是预览版,不过功能已经可用. NuGet 地址:https:/ ...

随机推荐

  1. Windows 10 LTSC启用Microsoft Store的方法

    新建msreg.bat文件,并编辑内容如下: ========== @echo off :: BatchGotAdmin :------------------------------------- ...

  2. [oeasy]python0109_tty_打字头_电传打字机_字模_点阵字库

    点阵字库 回忆上次内容 上次回顾了 字符字型 的 进化过程 从 谷腾堡 活字 到 罗马正字 和 意大利斜体   罗马帝国战斗力的征服 和 基督教文化传播 使得 拉丁字符 在日耳曼语地区广泛传播 种葡萄 ...

  3. [oeasy]python0026_刷新时间_延迟时间_time_sleep_死循环_while_True

    ​ 刷新时间 回忆上次内容 time 是一个 ​​module​ import 他可以做和时间相关的事情 time.time() 得到当前时间戳 time.localtime() 得到本地时间元组 l ...

  4. 理解es6 Promise的resolve和reject方法

    Promise.resolve() 有时需要将现有对象转为 Promise 对象,Promise.resolve方法就起到这个作用. const jsPromise = Promise.resolve ...

  5. QT 的 ModelView

    QApplication a(argc, argv); QDirModel model;    //QDirModel,   问文件目录树 QTreeView tree;    QListView l ...

  6. VUE系列---深度解析 Vue 优化策略

    在前端开发中,性能优化一直是一个重要的课题.Vue.js 提供了多种优化策略,帮助开发者构建高性能的应用.本文将深入解析以下几个优化策略: 使用 v-once.v-if 和 v-show 的区别和优化 ...

  7. whk随记

    金刚烷,实际上是p4把磷换成碳,然后在每两个碳之间再加一个碳,氢再补齐,由于碳都是sp3杂化,所以画出来并不对称,但实际上是对称的,一氯代物只有两种,像p4o6一样,而p4o10实际上是每个磷外面再连 ...

  8. 【SpringSecurity】01 授权、认证、注销

    [前提情要] Security学习地址: https://www.bilibili.com/video/BV1KE411i7bC 狂神的微信笔记: https://mp.weixin.qq.com/s ...

  9. 个人的谷歌学术主页:https://scholar.google.co.kr/citations?user=jHvm-VAAAAAJ&hl=en

    主页地址: https://scholar.google.co.kr/citations?user=jHvm-VAAAAAJ&hl=en

  10. 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 ...