EF Core 中实现 动态数据过滤器

前言   在项目开发中,我们很多时候都会设计 软删除、所属用户 等等一系列字段 来方便我们在业务查询的时候进行各种过滤   然后引申的问题就是:     在业务查询的时候,我们要如何加上这些条件?或者动态禁用某些查询条件呢? EF Core自带的全局过滤查询功能   EF Core提供了一个HasQueryFilter 供我们在查询的时候进行预置部分筛选条件   例如:    builder.HasQueryFilter(x => !x.IsDelete);   这样查询的时候 EF Core 会自动帮我们实现过滤   然后如果不想使用的时候可以全部忽略    DbSet.IgnoreQueryFilters();   咋一看 很完美   然后我们实际操作的时候   1.我是不是每个Entity里面是不是都要配置一次呢?   2.我只想禁用部分筛选条件呢?   3.我的查询条件的某些参数要动态呢?     例如和用户相关的数据等等     (有些人可能会说 我想办法把User的信息注入到DbContext里面不就可以了 假如我还要别的信息呢 还是接着注入?)   这就是理论和实践之间的差距   然后再网上找好久,找到了 EntityFramework-Plus (开源免费)   https://github.com/zzzprojects/EntityFramework-Plus   官网地址: http://entityframework-plus.net/   内置了很多功能 本篇只针对查询过滤做说嘛 EntityFramework-Plus 查询过滤功能   1.QueryFilterManager   QueryFilterManager 主要用来预设全局过滤   例如:   QueryFilterManager.Filter(q => q.Where(x => x.IsActive));   var ctx = new EntitiesContext();   QueryFilterManager.InitilizeGlobalFilter(ctx);   这样即可。。。   但是需要提前注意的是 QueryFilterManager 预设后是无法更改的   无法更改这是在 谷歌的时候 作者正好回复的别人的时候看到的   就和我们之前第三点 动态 冲突了   然后只能再看别的方式了   2.Filter   Z.EntityFramework.Plus 提供了 通过DbContext 的扩展方式来进行注入筛选条件的方式   例如:   var ctx = new EntitiesContext();   ctx.Filter(MyEnum.EnumValue, q => q.Where(x => x.IsDomestic))   //禁用指定键值查询条件   ctx.Filter(MyEnum.EnumValue).Disable();   var dogs = ctx.Dogs.ToList();   //启用指定键值查询条件   ctx.Filter(MyEnum.EnumValue).Enable();   // SELECT * FROM Dog WHERE IsDomestic = true   var dogs = ctx.Dogs.ToList();   这样好像符合我们的需求   3.AsNoFilter   禁用条件   例如:    var ctx = new EntitiesContext();   this.Filter(q => q.Where(x => x.IsActive));   // SELECT * FROM Customer WHERE IsActive = true   var list = ctx.Customers.ToList();   // SELECT * FROM Customer   var list = ctx.Customers.AsNoFilter().ToList();   AsNoFilter()后如何启用 指定查询条件 作者好像没有做相应扩展 ,后面会给出对应扩展方法 ----------------------------------------------------------------------------------------------------------------------------------------------------------- 说了这么多 理论补完了 实际操作的时候呢?   1.这些条件如何注入进来呢?   2.如何可以让我任意扩展呢?   3.假如我们操作时通过仓储 ,而不是 直接通过DbContext 呢? 如何封装 这边演示通过我自己的开源项目做为事例:   github : https://github.com/wulaiwei/WorkData.Core   主要依赖的框架   1.AutoFac   2.EF Core   3.Z.EntityFramework.Plus -----------------------------------------------------------------------------------------------------------------------------------------     对于我们来说 我们无论使用多少个数据筛选器 返回的都应该是同一个返回值 ,我们去看 DbContext.Filter(....) 会发现他的返回值都是 BaseQueryFilter   针对这个 我们可以得到两条信息 我们需要 传入 DbContext 和 一个返回值为 BaseQueryFilter 的方法   所以 我们定义如下接口 IDynamicFilter View Code   这样我们这边就得到了一个标准   例如 我们我们需要一个 所属用户和 软删除 的数据筛选器 我们只需要继承他即可   我们如何区分他们呢?   我们在之前使用 Z.EntityFramework.Plus 是看到了 可以设置筛选器的Key   所以 我们也同样扩展个属性 DynamicFilterAttribute 来作为他们的名字 View Code   然后我们定义我们的 所属用户和 软删除 的数据筛选器 并为他们设置名称   CreateDynamicFilter View Code   说明:   var workdataSession = IocManager.Instance.Resolve();   用来获取你所需要的 传参   IocManager.Instance.Resolve 是WorkData 关于Ioc的封装 源码可以参见git 或者上一篇博客   SoftDeleteDynamicFilter View Code    这样 我们所有接口 和实现定义好了 如何管理呢?   1.将继承 IDynamicFilter 的注入到Ioc里面 View Code   说明:   1.ITypeFinder 是从 nopcommerce 抽离出来的反射方法 已集成到WorkData 百度即可查询到相应说明文档   2.通过 GetCustomAttribute 获取 DynamicFilterAttribute 的属性名称 作为注册到Ioc名称   2.如何设置一个启用数据筛选器呢?我们这边定义个配置文件 通过 .net core 提供的程序进行配置文件注入 View Code "DynamicFilterConfig": { "DynamicFilterList": [ "CreateUserId", "SoftDelete" ] } 如何注入配置文件 可以通过百度或者查看workdata源码 即可 这不做说明   3.如何管理呢?什么时候统一添加到 DbContext呢?   我们这边定义一个DynamicFilterManager 提供一个 字典集合 来暂存所以的 IDynamicFilter,同时提供一个方法来进行初始化值 View Code   然后我们在DbContext里面的 OnModelCreating 进行初始化 View Code   初始化完成后如何将条件付给 DbContext 呢?   在DynamicFilterManager 中我们提供了一个扩展方法 AddDynamicFilter 你可以在你创建 DbContext 的时候调用 View Code   在WorkData中 我们则需要在EfContextFactory 进行调用   dbContext = _resolver.Resolve();   //初始化拦截器   dbContext.AddDynamicFilter(); View Code   这样我们的筛选器已经全部注入完成了   还剩下一个我们之前说的   AsNoFilter()后如何启用 指定查询条件 作者好像没有做相应扩展 ,后面会给出对应扩展方法   通过查看源码后 View Code Z.EntityFramework.Plus 提供了一个 ApplyFilter 所以 我们基于这个 做个扩展 View Code 这样 我们可以传入指定的筛选器名称 启用自己想要的 最终我们的仓储就变成了这样: View Code 说明:仓储的设计理念是从 ABP中抽离出来的 最后附测试 启用的筛选器为 "CreateUserId", "SoftDelete" View Code 分类: WorkData 好文要顶https://www.cnblogs.com/wulaiwei/p/9561830.html
50000+
5万行代码练就真实本领
17年
创办于2008年老牌培训机构
1000+
合作企业
98%
就业率

联系我们

电话咨询

0532-85025005

扫码添加微信