全局查询筛选器适用场景 以及各场景示例

EF Core中的全局查询筛选器(Global Query Filters)是一种强大的功能,可以在实体框架的DbContext级别为特定的EntityType设置默认的过滤条件。这些筛选器自动应用于所有涉及到相关实体的LINQ查询中,无论是直接查询还是通过Include或导航属性间接引用的情况。

以下是一些适用场景:

  • 多租户: 在多租户应用程序中,每个租户的数据应该彼此隔离。通过使用全局查询筛选器,可以轻松确保每次查询仅返回特定租户的数据,而无需在每个查询中显式添加Where子句。

  • **软删除:**软删除是一种数据管理策略,允许在数据库中保留已删除的数据,而不是完全从数据库中移除。通过使用全局查询筛选器,可以自动排除那些被标记为已删除的数据行,从而在查询结果中只包含未删除的数据。

  • 数据访问权限 :在某些应用中,您可能基于用户的角色或权限来限制他们可以访问的数据。全局查询筛选器可以确保即使忘记了添加权限检查,查询也仍然只返回用户可以访问的数据。


软删除

软删除是一种数据管理策略,它允许在数据库中保留已删除的数据,而不是完全从数据库中移除。这种策略通常通过添加一个布尔类型的列(如IsDeleted)来实现,该列标记着每行数据是否已被逻辑删除。

以下是一个示例

1.定义实体:首先,你需要定义包含特定属性的实体类,例如用于软删除的IsDeleted属性。

cs 复制代码
public class MyEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public bool IsDeleted { get; set; }
}
  1. 配置筛选器:接下来,在OnModelCreating方法中使用HasQueryFilter API为实体类型配置查询筛选器。这些筛选器以LINQ查询谓词的形式存在,并自动应用于所有相关的查询操作。
cs 复制代码
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>()
        .HasQueryFilter(e => !e.IsDeleted);
}
  1. 执行删除操作:当你需要删除一个实体时,只需将IsDeleted属性设置为true,而不是实际从数据库中删除它。
cs 复制代码
var entity = new MyEntity { Id = 1, Name = "Example" };
context.MyEntities.Add(entity);
await context.SaveChangesAsync();

entity.IsDeleted = true;
await context.SaveChangesAsync();

4.恢复删除的数据:如果你意外删除了数据,你可以轻易地通过更改IsDeleted标志来恢复。

cs 复制代码
entity.IsDeleted = false;
await context.SaveChangesAsync();

优缺点:

  • 优点

    • 恢复数据 :如果你意外删除了数据,你可以轻易地通过更改IsDeleted标志来恢复。
    • 审计和历史记录:保留了数据的历史记录,有助于进行审计和分析。
    • 提高性能:在某些情况下,软删除可以提高性能,因为它避免了实际的数据库删除操作。
  • 缺点

    • 维护开销:需要定期清理未使用的数据,否则可能会占用过多的存储空间。
    • 查询复杂性 :每个查询都需要包含IsDeleted条件,除非确实需要访问已删除的数据。

多租户

多租户架构是一种将多个租户(用户或组织)共享同一套应用程序或系统的方式,同时保持每个租户的数据隔离性。这种架构模式在许多现代应用程序中被广泛使用,例如云服务提供商、SaaS应用程序等。

以下是一个示例

  1. 定义实体:首先,你需要定义包含特定属性的实体类,例如用于标识租户的TenantId属性。、
cs 复制代码
public class MyEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int TenantId { get; set; }
}
  1. 配置筛选器:接下来,在OnModelCreating方法中使用HasQueryFilter API为实体类型配置查询筛选器。这些筛选器以LINQ查询谓词的形式存在,并自动应用于所有相关的查询操作。
cs 复制代码
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>()
        .HasQueryFilter(e => e.TenantId == _currentTenantId);
}
  1. 执行查询操作:当你需要查询数据时,只需根据当前租户的ID进行过滤即可。
cs 复制代码
// 假设当前租户的ID为1
var entities = context.MyEntities.ToList();
  1. 添加新记录:当你需要添加一个新记录时,只需设置TenantId属性为当前租户的ID即可。
cs 复制代码
var entity = new MyEntity { Name = "Example" };
entity.TenantId = _currentTenantId;
context.MyEntities.Add(entity);
await context.SaveChangesAsync();

优缺点:

  • 优点

    • 可定制性和灵活性:每个租户可以根据需要定制自己的数据视图和功能。
    • 简化维护:可以在一个集中的位置更新和维护应用程序。
  • 缺点

    • 数据隔离:需要小心设计以防止数据泄露或混肴。
    • 性能挑战:如果所有租户都在同一时间活跃,可能会对性能造成压力。
    • 备份和恢复:可能需要更复杂的备份和恢复策略来满足不同租户的需求。

数据访问权限

下面是一个示例:

假设我们有一个名为User的实体类,其中包含一个名为Role的角色字段,表示用户的角色。我们希望在执行查询时自动过滤掉不属于特定角色的用户。

首先,我们需要在DbContext的OnModelCreating方法中为User实体类型配置全局查询筛选器。

cs 复制代码
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<User>()
        .HasQueryFilter(u => u.Role == "Admin");
}

上述代码将自动应用一个筛选条件,只返回角色为"Admin"的用户记录。

接下来,我们可以执行普通的LINQ查询来获取所有管理员用户。

cs 复制代码
var adminUsers = context.Users.ToList();

由于已经配置了全局查询筛选器,上述查询将自动过滤掉非管理员用户,并返回所有管理员用户列表。

全局查询筛选器仅适用于直接查询和通过导航属性引用的情况。如果需要对关联表进行数据访问权限的查询,可以在关联表中也使用类似的全局查询筛选器。还可以根据需要自定义全局查询筛选器的表达式,以满足更复杂的业务需求。


忽略全局查询过滤器( IgnoreQueryFilters()

如果你想在执行针对Student实体类型的查询时忽略全局查询过滤器,可以使用**IgnoreQueryFilters()**方法。

例如,以下代码将忽略全局查询过滤器并返回所有Student记录:

cs 复制代码
var allStudents = context.Students.IgnoreQueryFilters().ToList();

通过调用IgnoreQueryFilters()方法,你可以暂时禁用全局查询过滤器,以便执行不受其影响的查询。

相关推荐
是小李呀~3 分钟前
【工作梳理】怎么把f12里面的东西导入到postman
java
攀小黑3 分钟前
Java 多线程加锁 synchronized 关键字 字符串当做key
java·开发语言
专注VB编程开发20年6 分钟前
Aspose.words,Aspose.cells,vb.net,c#加载许可证,生成操作选择:嵌入的资源
c#·word·.net·vb.net
每次的天空12 分钟前
Kotlin 作用域函数:apply、let、run、with、also
android·开发语言·kotlin
小林熬夜学编程16 分钟前
【高并发内存池】第八弹---脱离new的定长内存池与多线程malloc测试
c语言·开发语言·数据结构·c++·算法·哈希算法
余华余华16 分钟前
2024年蓝桥杯Java B组省赛真题超详解析-分布式队列
java·职场和发展·蓝桥杯
andy552018 分钟前
.NET 使用 WMQ 连接Queue 发送 message 实例
xml·c#·wmq·c# 连接wmq·发送消息到wmq
破罐子不摔19 分钟前
【C#使用S7.NET库读取和写入西门子PLC变量】
java·c#·.net
MariaH19 分钟前
Sequelize模型初探
前端·后端
码视野20 分钟前
基于SpringBoot的河道水情大数据可视化分析平台设计与实现(源码+论文+部署讲解等)
spring boot·后端·物联网·信息可视化·论文·本科毕业论文·计算机专业毕业论文