主要参考

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. var 和 let 在 jQuery中的区别

    下面通过代码案例来进一步解释 var 和 let 在 jQuery link 函数中的区别: (function ($) { $.fn.link = function () { // Example ...

  2. Raid0创建

    实验步骤 步骤1: 确认硬盘 确认你的硬盘设备名. [root@servera ~]# lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 ...

  3. [rCore学习笔记 012]彩色化LOG

    实验要求 实现分支:ch1 完成实验指导书中的内容并在裸机上实现 hello world 输出. 实现彩色输出宏(只要求可以彩色输出,不要求 log 等级控制,不要求多种颜色) 隐形要求 可以关闭内核 ...

  4. SSL/TLS 深入浅出

    SSL,https(HTTP over SSL), X.509, SSL 证书 ,证书申请 /导入/签发, 等名词,想必有一定工作经验的小伙伴,一定都会略有耳闻,或者至少也听神边大神念叨过.虽然司空见 ...

  5. cgroup限制进程cpu

    编写一个死循环脚本 [root@workstation ~]# cat circle.sh #!/bin/bash a=1 while true do let a++ done 查看top 使用cgr ...

  6. 统计平台广告推送工具支持百度、51拉、CNZZ 用法详解

    此软件用于伪造站长统计的搜素关键词,可以模拟百度.360.搜狗等搜索引擎来路 支持自定义刷词次数.多线程支持自定义线程数,速度更快 支持指定网址推广,带来更精确的网站IP来路 一键导入几十万个网站,支 ...

  7. [香橙派开发系列]3b系统安装和使用vscode进行远程连接

    目录 前言 一.下载镜像和安装系统 二.使用串口助手进行调试 三.查看系统的ip地址 四.使用vscode连接香橙派 最后 前言 之前研究中断的时候一直出现问题,我怀疑是因为zero 3不支持,所以一 ...

  8. 【MySQL】拆分经纬度字段

    数据结构: 表中一字段存储经度和纬度: +---------------------------+ | INSTALL_LOLA_NUM | +---------------------------+ ...

  9. 【Mybatis + Spring】 Mybatis - Spring 结合

    环境搭建 EvBuild 软件环境准备 - MySQL 5.0 + - IDEA 2018 + - JDK1.8 + 依赖包相关 - Junit单元测试 - JDBC驱动 - Mybatis 组件 - ...

  10. 【Java】数组强转问题

    问题产生 问题代码: List<String> strs = new LinkedList<String>(); // 中间有添加元素的操作,这里省略... // 这里toAr ...