Общий фильтр c включенных сущностей в Entity Framework 6 - PullRequest
0 голосов
/ 09 мая 2020

Я хотел бы знать, возможен ли следующий сценарий: я создал общий репозиторий c для обработки операций CRUD на нескольких объектах. Учитывая, что у меня есть реализация мягкого удаления для сущностей, для определенной сущности, которая связана с другими сущностями, я хотел бы отфильтровать включенные сущности на основе свойства, скажем, 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;
     }
}

BaseEntity class выглядит так, и все классы (включая те, которые я хотел бы отфильтровать в методе Include) наследуются от него:

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

Я знаю, что включенные сущности можно фильтровать на уровне, на котором конкретный объект доступен, но мне было интересно, возможно ли это в классе репозитория generi c, поэтому мне не нужно проверять свойство IsDeleted для каждого запроса в указанных репозиториях c.

Спасибо.

1 Ответ

0 голосов
/ 09 мая 2020

Допустим, у вас есть два класса Foo и FooContainer, например:

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

и репо:

    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);
    }

Чтобы получить FooContainer сущности с Foo включено, вы бы назвали репо следующим образом:

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

Переходя к методу Get в Repository классе:

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

включить комментарий - на данный момент вы знаете только, что include - это Fun c, то есть FooContainer в качестве параметра и возвращает object. Несмотря на то, что вы знаете, что этот объект имеет флаг IsDeleted, это все еще object - это означает, что с текущей сигнатурой метода Get невозможно добавить фильтрацию Where к включенным объектам.

Для этого вам необходимо указать Expression<Func<T, bool>> includeFilter для каждой включенной сущности

...