我可以在Entity Framework中进行模型级过滤吗?

时间:2013-01-17 16:20:42

标签: .net entity-framework

在最新版本的Lightswitch中,他们添加了一个查询pipleline方法,该方法允许您捕获对数据库的所有查询请求,并添加过滤器。这允许您添加(例如)将数据限制为“active”标志为true的数据的过滤器,而不必担心在您编写的每个查询中执行此操作。

现在,鉴于Lightswitch中的数据库级别的东西都是基于Entity Framework构建的,我想知道那里是否有类似的东西。我正在开发一个非常大的项目,在大约50或60个单独的存储库中有大量查询,并且实际上并不想让每个开发人员遍历每个存储库中的每个查询并添加代码来检查活动标志。除了所涉及的时间之外,错过查询的可能性很高,有人忘记将其包含在将来的查询中的可能性很高。

任何人都知道这是否可以在实体框架中的低级别完成?感谢

1 个答案:

答案 0 :(得分:6)

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

一。如果您已经抽象了您的存储库,那么您可以执行以下操作:

您的所有实体都可以从Abstract类或Interface with和Active属性继承,您的代码将是:

    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。像这样:

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

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

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

修改

三。如果生成的DbContext暴露给客户端代码,则可以执行以下操作:

    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模板。更容易获取生成的代码,转换和修改。