ef core提供了Global Query Filters特性来实现多租户与软删除,收集了一些实现方法。

最简单的例子是微软官方的特性解释。

https://docs.microsoft.com/en-us/ef/core/querying/filters

 modelBuilder.Entity<Post>().HasQueryFilter(p => !p.IsDeleted);

比较全面的实现可参考:

https://gunnarpeipman.com/ef-core-global-query-filters/

需要注意Cache问题:

https://docs.microsoft.com/en-us/ef/core/modeling/dynamic-model

https://spin.atomicobject.com/2019/01/29/entity-framework-core-soft-delete/

https://www.meziantou.net/entity-framework-core-soft-delete-using-query-filters.htm

https://comment-it.co.uk/entity-framework-core-soft-delete-workaround/

其中如果需要扫描model自动注册所有实体,属于是高阶用法

构建Expression的代码难以理解,不便后人维护,不过学习一下对理解lambda表达式的底层还是有帮助的

// 1. Add the IsDeleted property
entityType.GetOrAddProperty("IsDeleted", typeof(bool)); // 2. Create the query filter var parameter = Expression.Parameter(entityType.ClrType); // EF.Property<bool>(post, "IsDeleted")
var propertyMethodInfo = typeof(EF).GetMethod("Property").MakeGenericMethod(typeof(bool));
var isDeletedProperty = Expression.Call(propertyMethodInfo, parameter, Expression.Constant("IsDeleted")); // EF.Property<bool>(post, "IsDeleted") == false
BinaryExpression compareExpression = Expression.MakeBinary(ExpressionType.Equal, isDeletedProperty, Expression.Constant(false)); // post => EF.Property<bool>(post, "IsDeleted") == false
var lambda = Expression.Lambda(compareExpression, parameter); builder.Entity(entityType.ClrType).HasQueryFilter(lambda);

lambda通过全局函数借助统一的父类实现,当然实际开发中,可以改为接口扫描来做。需要注意多个filter条件需要通过“与”操作一起设置,否则后面设置会覆盖前面的设置。

public void SetGlobalQuery<T>(ModelBuilder builder) where T : BaseEntity
{
builder.Entity<T>().HasKey(e => e.Id);
builder.Entity<T>().HasQueryFilter(e => e.TenantId == _tenant.Id);
}
private static IList<Type> GetEntityTypes()
{
if (_entityTypeCache != null)
{
return _entityTypeCache.ToList();
} _entityTypeCache = (from a in GetReferencingAssemblies()
from t in a.DefinedTypes
where t.BaseType == typeof(BaseEntity)
select t.AsType()).ToList(); return _entityTypeCache;
}
protected override void OnModelCreating(ModelBuilder builder)
{
var navigation = builder.Entity<ProductCategory>()
.Metadata
.FindNavigation(nameof(ProductCategory.Products)); navigation.SetPropertyAccessMode(PropertyAccessMode.Field); foreach (var type in GetEntityTypes())
{
var method = SetGlobalQueryMethod.MakeGenericMethod(type);
method.Invoke(this, new object[] { builder });
} base.OnModelCreating(builder);
}

ef core SoftDelete Multi-tenancy 软删除、多租户实现 Global Query Filters的更多相关文章

  1. ef core实现无感知软删除

    很多web程序一般的偶不会设计真的物理删除了. 基本上都是在在数据库加一个标记,就得当作已经删除了.同时在查询的时候,过滤已经标记删除的数据 ef core实现软删除是非常简单的,直接在OnModel ...

  2. EntityFramework.DynamicFilters 实现软删除和租户过滤

    EntityFramework.DynamicFilters 实现软删除和租户过滤

  3. EF Core中Fluent Api如何删除指定数据表中的行

    这两天一直在研究在code first下如何删除数据表中的指定行,于是开始搜狗,后来百度,压根就找不到资料,后来一想可能我的搜索关键字有问题,而且ef core命令与ef的命令差不多,于是从这两个方面 ...

  4. 深入理解 EF Core:使用查询过滤器实现数据软删除

    原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...

  5. 【EF】Entity Framework Core 软删除与查询过滤器

    本文翻译自<Entity Framework Core: Soft Delete using Query Filters>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 注意 ...

  6. EF Core 实现多租户

    目录 SAAS 和多租户 多租户数据隔离方案 使用 EF Core 简单实现多租户 单数据库实现 多数据库实现 源代码 参考 SAAS 和多租户 SaaS(软件及服务)区别于其他应用程序的主要特征就是 ...

  7. 深入理解 EF Core:EF Core 写入数据时发生了什么?

    阅读本文大概需要 14 分钟. 原文:https://bit.ly/2C67m1C 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能 ...

  8. EF core 性能调优

    Entity Framework Core performance tuning – a worked example Last Updated: February 25, 2019 | Create ...

  9. DDD Code First 迁移数据实现EF CORE的软删除,值对象迁移配置

    感谢Jeffcky大佬的博客: EntityFramework Core 2.0全局过滤 (HasQueryFilter) https://www.cnblogs.com/CreateMyself/p ...

随机推荐

  1. Spring Cloud Alibaba 实战(十一) - Spring Cloud认证授权

    欢迎关注全是干货的技术公众号:JavaEdge 本文主要内容: 如何实现用户认证与授权? 实现的三种方案,全部是通过画图的方式讲解.以及三种方案的对比 最后根据方案改造Gateway和扩展Feign ...

  2. 深度学习VGG16模型核心模块拆解

    原文连接:https://blog.csdn.net/qq_40027052/article/details/79015827 注:这篇文章是上面连接作者的文章.在此仅作学习记录作用. 如今深度学习发 ...

  3. Asp.Net Core 内置IOC容器的理解

    Asp.Net Core 内置IOC容器的理解 01.使用IOC容器的好处 对接口和实现类由原来的零散式管理,到现在的集中式管理. 对类和接口之间的关系,有多种注入模式(构造函数注入.属性注入等). ...

  4. goweb-http协议

    先链接到一个我的另一篇有关HTTP的博客 第一次访问时会有些慢~~~ http协议 因为编写 Web 应用必须对 HTTP 有所了解,所以我们对 HTTP 进行介绍 HTTP 协议简介 HTTP 超文 ...

  5. WGS84、WebMercator、GCJ02和BD09坐标系简介与转换

    WGS84(GPS): 地心坐标系,空间直角坐标系,原点与地球质心重合,为GPS采用的坐标系,也是目前广泛使用的GPS全球卫星定位系统使用的坐标系. 通过GPS可以直接获取WGS84下的坐标(B,L, ...

  6. OpenCV:图像平滑和图像模糊处理

    导包: import numpy as np import cv2 import matplotlib.pyplot as plt def show(image): plt.imshow(image) ...

  7. Android 单选列表对话框 setSingleChoiceItems

    private Button button; private final CharSequence[] items = { "北京", "上海", " ...

  8. QT--HTTP图片下载器

    QT--HTTP图片下载器 1.http使用前提 QT       += core gui network    //必须加上network 2.必须头文件 #include <QNetwork ...

  9. MySQL数据库:注释及数据类型

    注释 /* 多行注释 */ # 单行注释 -- 单行注释(注意:两个但横线后面必须加空格) 数据类型 1.整形 ​ tinyint.smallint.mediumint.int.bigint ​ 小整 ...

  10. Django2.1.1与xadmin0.6.0遇到的坑(一)

    (1)django2.0把from django.core.urlresolvers修改成了django.urls 异常信息: ModuleNotFoundError: No module named ...