简体   繁体   English

实体框架向所有查询添加where子句

[英]Entity framework add where clause to all queries

I have a project that is using Entity framework and AspNet Identity. 我有一个使用实体框架和AspNet标识的项目。

One of the parameters of the IdentityUser is a deactivated field. IdentityUser的参数之一是停用字段。

Within the app, if I wanted to get the users, I would do this: 在应用程序中,如果我想吸引用户,我可以这样做:

var users = Context.Users //etc....

However, I do not want this query to return any deactivated users. 但是,我不希望该查询返回任何停用的用户。 I know I could do this 我知道我能做到

var users = Context.Users.Where(x => x.Deactivated != true);

However, I am reluctant to do this, as I am sure that in time someone will forget to add this where clause. 但是,我不愿意这样做,因为我确信随着时间的流逝,有人会忘记添加此where子句。

Is there a way for entity to do this automatically to all context queries? 实体是否可以对所有上下文查询自动执行此操作? I have found this: 我发现了这一点:

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

But I do not have EF core and cannot upgrade to it. 但是我没有EF核心,无法升级到它。

I know I could make a wrapper function and call this, but I am trying to find a better solution... 我知道我可以做一个包装器函数并调用它,但是我试图找到一个更好的解决方案...

I often use a combination of XXXStore members and XXX members where the XXXStore is the DBSet and the XXX is a query with AsNoTracking() . 我经常使用XXXStore成员和XXX成员的组合,其中XXXStoreDBSetXXX是使用AsNoTracking()的查询。 I then use the XXX members in queries responding to GET s and the XXXStore only when I want to update the database. 然后,仅在我想更新数据库时,才在响应GET的查询中使用XXX成员,而在XXXStore使用。 Eg 例如

    public DbSet<User> UserStore { get; set; }

    public IQueryable<User> Users => UserStore.AsNoTracking();

This gives the advantage of not tracking entities that won't be updated, but with a DRY approach that means not adding the AsNoTracking() verbosely all over the place. 这具有以下优点:不跟踪不会更新的实体,而是采用DRY方法,这意味着不会在整个地方都AsNoTracking()添加AsNoTracking()

This approach can easily be combined with a where clause: 这种方法可以很容易地与where子句结合使用:

    public DbSet<User> UserStore { get; set; }

    public IQueryable<User> Users => UserStore.AsNoTracking().Where(u => !u.Deactivated);

Filters can also work, but an advantage to this approach is that it's easy to make an exception when you really do need to access a deactivated user, too. 过滤器也可以工作,但是这种方法的优点是,当您确实确实确实需要访问停用的用户时,很容易将其作为例外。

You can use Global Filters: 您可以使用全局过滤器:

protected override void OnModelCreating(ModelBuilder modelBuilder){
    modelBuilder.Entity<Blog>().Property<string>("TenantId").HasField("_tenantId");
    // Configure entity filters
    modelBuilder.Entity<Blog>().HasQueryFilter(b => EF.Property<string>(b, "TenantId") == _tenantId);
    modelBuilder.Entity<Post>().HasQueryFilter(p => !p.IsDeleted);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM