主要参考

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. ModuleNotFoundError: No module named 'import_export'

    当你遇到 "ModuleNotFoundError: No module named 'import_export'" 错误时,这表示你的 Python 脚本或应用程序试图导入名为 ...

  2. 【WSDL】01 JAX-WS 入门案例

    去年这个时候工作遇见时暂时总结的笔记: https://www.cnblogs.com/mindzone/p/14777493.html 当时也不是很清楚,直到最近前同事又遇上了这项技术, 除了WSD ...

  3. 【H5】05 高阶文字排版

    摘自: https://developer.mozilla.org/zh-CN/docs/Learn/HTML/Introduction_to_HTML/Advanced_text_formattin ...

  4. 【Scala】01 基础了解

    Features 特性 1.基于JVM,完全兼容Java 2.同样具有跨平台,可移植,垃圾回收 3.比Java更加的面向对象[完全面向对象] 4.函数式编程 5.面向大数据处理,对集合容器框架有一定的 ...

  5. 【Zookeeper】01 概述 & 基础部署

    背景: 随着互联网技术的发展,企业对计算机系统的计算,存储能力要求越来越高,各大IT企业都在追求高并发,海量存储的极致, 在这样的背景下,单纯依靠少量高性能单机来完成计算机,云计算的任务已经无法满足需 ...

  6. conda/anconda报错:WARNING conda.models.version:get_matcher(556): Using .* with relational operat

    conda/anconda报错:WARNING conda.models.version:get_matcher(556): Using .* with relational operat 解决方法, ...

  7. baselines算法库common/vec_env/util.py模块分析

    util.py模块代码: """ Helpers for dealing with vectorized environments. """ ...

  8. baselines算法库baselines/common/input.py模块分析

    baselines算法库baselines/common/input.py模块代码: import numpy as np import tensorflow as tf from gym.space ...

  9. code: 'ERR_OSSL_EVP_UNSUPPORTED' 报错解决

    报错: Error: error:0308010C:digital envelope routines::unsupported at new Hash (node:internal/crypto/h ...

  10. 代码随想录Day5

    242.有效的字母异位词 给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词. 注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词. 示例 ...