ef core SoftDelete Multi-tenancy 软删除、多租户实现 Global Query Filters
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的更多相关文章
- ef core实现无感知软删除
很多web程序一般的偶不会设计真的物理删除了. 基本上都是在在数据库加一个标记,就得当作已经删除了.同时在查询的时候,过滤已经标记删除的数据 ef core实现软删除是非常简单的,直接在OnModel ...
- EntityFramework.DynamicFilters 实现软删除和租户过滤
EntityFramework.DynamicFilters 实现软删除和租户过滤
- EF Core中Fluent Api如何删除指定数据表中的行
这两天一直在研究在code first下如何删除数据表中的指定行,于是开始搜狗,后来百度,压根就找不到资料,后来一想可能我的搜索关键字有问题,而且ef core命令与ef的命令差不多,于是从这两个方面 ...
- 深入理解 EF Core:使用查询过滤器实现数据软删除
原文:https://bit.ly/2Cy3J5f 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能会去除一些本人实在不知道如何组织 ...
- 【EF】Entity Framework Core 软删除与查询过滤器
本文翻译自<Entity Framework Core: Soft Delete using Query Filters>,由于水平有限,故无法保证翻译完全正确,欢迎指出错误.谢谢! 注意 ...
- EF Core 实现多租户
目录 SAAS 和多租户 多租户数据隔离方案 使用 EF Core 简单实现多租户 单数据库实现 多数据库实现 源代码 参考 SAAS 和多租户 SaaS(软件及服务)区别于其他应用程序的主要特征就是 ...
- 深入理解 EF Core:EF Core 写入数据时发生了什么?
阅读本文大概需要 14 分钟. 原文:https://bit.ly/2C67m1C 作者:Jon P Smith 翻译:王亮 声明:我翻译技术文章不是逐句翻译的,而是根据我自己的理解来表述的.其中可能 ...
- EF core 性能调优
Entity Framework Core performance tuning – a worked example Last Updated: February 25, 2019 | Create ...
- DDD Code First 迁移数据实现EF CORE的软删除,值对象迁移配置
感谢Jeffcky大佬的博客: EntityFramework Core 2.0全局过滤 (HasQueryFilter) https://www.cnblogs.com/CreateMyself/p ...
随机推荐
- C++ std::list 和 std::forward_list 的差别及其成员函数差异对比
主要差别: list 是双向链表,forward_list 是双向链表. 成员函数差异: 函数名 list forward_list back() has no size() has no inser ...
- win7安装centos7虚拟机
1. 场景描述 因测试中需要linux集群,目前的服务器不太方便部署,需要本机(windows7)启动多个linux虚拟机,记录下,希望能帮到需要的朋友. 2. 解决方案 2.1 软件准备 (1)使用 ...
- MAC 软件提示已损坏,需要移到废纸篓的解决方法
解决方法一: 允许任何来源的应用.在系统偏好设置里,打开“安全性和隐私”,将“允许从以下位置下载的应用程序”设置为“任何来源“.当然,这个设置已经无法在Mac OS Sierra上完成了. 在Mac ...
- 松软科技web课堂:SQLServer之LAST() 函数
LAST() 函数 LAST() 函数返回指定的字段中最后一个记录的值. 提示:可使用 ORDER BY 语句对记录进行排序. SQL LAST() 语法 SELECT LAST(column_nam ...
- JS基础语法---创建对象---三种方式创建对象:调用系统的构造函数;自定义构造函数;字面量的方式
创建对象三种方式: 调用系统的构造函数创建对象 自定义构造函数创建对象(结合第一种和需求通过工厂模式创建对象) 字面量的方式创建对象 第一种:调用系统的构造函数创建对象 //小苏举例子: //实例化对 ...
- JS 验证
JS 验证 JavaScript 可用来在数据被送往服务器前对 HTML 表单中的这些输入数据进行验证. JavaScript 表单验证 JavaScript 可用来在数据被送往服务器前对 HTML ...
- Android 上下文菜单 PopupMenu
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); s ...
- Android8.1 源码修改之通过黑名单屏蔽系统短信功能和来电功能
前言 之前写过一篇Android6.0 的屏蔽系统短信功能和来电功能,具体看这里 同样的最近有个新需求,需要将8.1 设备的来电功能和短信功能都屏蔽掉,特殊产品就是特殊定制,那就开始吧. 屏蔽短信功能 ...
- [b0044] numpy_快速上手
1 概念理清 2 创建数组 2.1 f1= np.array( [ [1,2,3,4], [2,3,4,5], [3,4,5,6] ]) 其他代码 a= np.array([ [ [3.4,5,6,8 ...
- curl的使用指南
一.查看网页源码 直接在curl命令后加上网址,就可以看到网页源码.我们以网址www.sina.com为例(选择该网址,主要因为它的网页代码较短): $ curl www.sina.com M ...