简体   繁体   English

在 Entity Framework 6 中过滤通用包含的实体

[英]Filter generic included entities in Entity Framework 6

I would like to know if the following scenario would be possible: I created a generic repo for handling CRUD operation on multiple entities.我想知道以下情况是否可行:我创建了一个通用存储库来处理多个实体上的 CRUD 操作。 Given that I have soft delete implementation on the entities, for a certain entity that relates with other entities, I would like to filter the included entities based on a property, let's say, IsDeleted.鉴于我对实体进行了软删除实现,对于与其他实体相关的某个实体,我想根据属性过滤包含的实体,比如 IsDeleted。

public abstract class Repository<T, TOrderBy> where T : BaseEntity
{
   ...
    protected IQueryable<T> Get(Expression<Func<T, bool>> filter = null,
        params Expression<Func<T, object>>[] includes)
    {
        var query = Set.AsQueryable();

        if (filter != null)
        {
            query = query.Where(x => !x.DeletedAt.HasValue).Where(filter);
        }

        if (includes != null)
        {
            foreach (var include in includes)
            {
                query = query.Include(include); // In here i would like to also filter the included entities based on the IsDeleted property
            }
        }

        return query;
     }
}

The BaseEntity class looks like this, and all classes (including the ones that I would like to filter in the Include method) inherit from it: BaseEntity class 看起来像这样,所有类(包括我想在 Include 方法中过滤的类)都继承自它:

 public abstract class BaseEntity
 {
     public bool IsDeleted { Get; Set; }
 }

I know that the included entities can be filter on the level where the concrete entity is available, but I was wondering if this is possible on the generic repository class, so I don't need to check the IsDeleted property for each query in the specific repositories.我知道包含的实体可以在具体实体可用的级别上进行过滤,但我想知道这是否可以在通用存储库 class 上进行,所以我不需要检查特定实体中每个查询的 IsDeleted 属性存储库。

Thanks.谢谢。

Let's say you have two classes Foo and FooContainer like this:假设您有两个类FooFooContainer ,如下所示:

    public class Foo : BaseEntity
    {
        public int Id { get; set; }
    }
    public class FooContainer : BaseEntity
    {
        public int Id { get; set; }
        public virtual Foo Foo { get; set; }
    }

and a repo:和一个回购:

    public class FooContainerRepository : Repository<FooContainer, object>
    {
        public IQueryable<FooContainer> GetFooContainers(Expression<Func<FooContainer, bool>> filter = null,
         params Expression<Func<FooContainer, object>>[] includes) => base.Get(filter, includes);
    }

In order to get FooContainer entities with Foo included you would call the repo like this:为了获得包含FooFooContainer实体,您可以像这样调用 repo:

            var repo = new FooContainerRepository();
            repo.GetFooContainers(null, fc => fc.Foo);

Moving on to Get method in Repository class:转到Repository class 中的Get方法:

                foreach (var include in includes)
                {
                    query = query.Include(include); // *include coment*
                }

include coment - at this point you only know that include is Func that thats FooContainer as a param and returns an object . include 注释- 此时您只知道include是 Func ,即FooContainer作为参数并返回object Even though u know that object has the IsDeleted flag, its still just an object - meaning that with current Get method signature it is not possible to add Where filtering to included entities.即使您知道 object 具有IsDeleted标志,它仍然只是一个object - 这意味着使用当前的Get方法签名无法将Where过滤添加到包含的实体。

In order to do that you would have to provide Expression<Func<T, bool>> includeFilter for each included entity为此,您必须为每个包含的实体提供Expression<Func<T, bool>> includeFilter

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

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