我可以在实体框架中进行模型级过滤吗? [英] Can I do model-level filtering in Entity Framework?

查看:52
本文介绍了我可以在实体框架中进行模型级过滤吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在最新版本的Lightswitch中,他们添加了查询pipleline方法,该方法使您可以捕获对数据库的所有查询请求,并添加过滤器。这样,您就可以添加(例如)一个过滤器,将数据限制为活动标志为true的数据,而不必担心在编写的每个查询中都这样做。

In the latest version of Lightswitch, they have added a query pipleline method that allows you to catch all query requests to the database, and add a filter. This allows you to add (for example) a filter that restricts the data to ones whose "active" flag is true, without having to worry about doing this on every query you write.

现在,鉴于Lightswitch中的数据库级内容全部基于Entity Framework构建,我想知道那里是否存在类似的东西。我正在做一个非常大的项目,在大约50或60个独立的存储库中有大量查询,因此,我并不想让每个开发人员仔细检查每个存储库中的每个查询并添加代码以检查活动标记。除了所涉及的时间外,丢失查询的机会也很高,有人忘记将其包含在将来的查询中的机会也很高。

Now, given that the database level stuff in Lightswitch is all built on Entity Framework, I was wondering if there is something similar there. I am working on a very large project, with loads of queries in around 50 or 60 separate repositories, and don't really want to have to ask every developer to go through every query in every repository and add code to check the active flag. Apart from the time involved, the chances of missing a query are high, as are the chances of someone forgetting to include it in a future query.

任何人都知道这是否可以在Entity Framework的较低级别完成?谢谢

Anyone know if this can be done at a low level in Entity Framework? Thanks

推荐答案

您必须能够拦截和修改谓词。

You have to be able to intercept and modify your predicates.

一个。如果您对存储库进行了抽象,则可以执行以下操作:

One. If you've abstracted your repository then you could do something like this:

所有实体都可以继承自具有Active属性的Abstract类或接口,并且您的代码将是:

All your Entities could inherit from an Abstract class or Interface with and Active property and your code would be:

    interface IActivatable {
        bool IsActive {get;set;}
    }


    class Repository<EntityType>
        where EntityType : class, IActivatable {

        private StackOverflowEntities context;


        public IQueryable<EntityType> GetAll() {

                return context.Set<EntityType>().Where(e => e.IsActive == false);

        }
    }

这样,GetAll返回IQueryable带有初始谓词,其余的将与AND相加。像这样:

That way the GetAll returns the IQueryable with an initial predicate, the rest will be added with an AND. Like so:

            Repository<Person> persons;
            var results = persons.GetAll().Where(p => p.IsMarried == false);

这将导致等于 p的谓词IsMarried == false& ;& p.IsActive == false

两个。如果根本不更改存储库代码或仅更改代码,则可以为每个表创建一个视图。该视图只可以在where子句中包含IsActive即可排除记录,然后根据这些视图重新加载EDMX-至少这是我们过去使用的方法。

Two. If it's not practical to change your repository code or code at all you could create a view for every table. The view can just include the IsActive in the where clause to exclude the records and then reload your EDMX based on those views - at least this is the way we used to do in back in the day.

编辑:

三个。如果您将生成的DbContext公开给客户端代码,则可以执行以下操作:

Three. If you have a generated DbContext exposed to client code you could do this:

    public partial class StackOverflowEntities : DbContext
    {
        public StackOverflowEntities()
            : base("name=StackOverflowEntities")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();            
        }

        public DbSet<Blog> Blogs {
            return this.Set<Blog>().Where(b => b.IsActive == false);
        }
    }

仅意味着您必须关闭自动编码生成或修改T4模板。只需获取生成的代码,关闭gen并进行修改即可。

Just means that you must turn off auto-code gen or modify the T4 template. Easier to just take the generated code, turn of the gen and modify.

这篇关于我可以在实体框架中进行模型级过滤吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆