Отфильтруйте Soft Deletes из DbContext Set () - PullRequest
1 голос
/ 07 декабря 2011

Как мне отфильтровать IsSoftDeleted элементов из этого DbSet?

var type = GetTypeFromString("Whatever");
var whatevers = Set(type);

Метод

public dynamic Set(Type type)
{
    var set = dbContext.Set(type);
    return set;
}

Модель

public class Whatever : BaseEntity
{
    public virtual string Name { get; set; }
}
public class BaseEntity
{
   public virtual int Id { get; set; }
   public virtual bool? IsSoftDeleted { get; set; }
}

РЕДАКТИРОВАТЬ: забыл показать Whatever происходит от BaseEntity

Ответы [ 2 ]

4 голосов
/ 07 декабря 2011

Ваш класс Wh независимо имеет свойство IsSoftDeleted, поэтому фильтровать нечего. Я собираюсь предположить, что бы ни происходило от BaseEntity.

Основная проблема в том, что IQueryable . Где-то на самом деле не существует: это метод расширения, а методы расширения не подходят для динамических типов. Если компилятор может видеть, что тип реализует IQueryable , вы можете ввести var.Where (...) и заставить компилятор преобразовать его в System.Linq.Queryable.Where (var, ...). Поскольку тип является динамическим в вашем примере, компилятор не знает, что он реализует IQueryable, и сообщит об ошибке, когда вы попытаетесь вызвать Where.

Вы можете привести DbSet к IQueryable (при условии, что у Type есть BaseEntity в качестве базового класса) и вызвать любой фильтр для этого. Вы на самом деле используете функцию динамического типа? Если нет, вы также можете рассмотреть возможность удаления своей пользовательской функции Set и использования функции DbContext.Set по умолчанию.

var query = (from e in (IQueryable<BaseEntity>)dbContext.Set(type)
             where e.IsSoftDeleted != true
             select e);

Примечание: это , а не то же самое, что и использование dbContext.Set (type) .Cast (): это не сработает, потому что DbSet и DbSet несовместимы Это можно сделать только с помощью IQueryable и других интерфейсов с аргументами типа «out».

3 голосов
/ 07 декабря 2011

Проблема в том, что Set(Type type) возвращает неуниверсальный DbSet. Чтобы применить свой фильтр, вы должны привести его к универсальному IQueryable<T>:

var set = ((IQueryable<BaseEntity>)dbContext.Set(type))
              .Where(be => be.IsSoftDeleted.HasValue && !be.IsSoftDeleted.Value);

Это работает, только если type получено из BaseEntity или BaseEntity, в противном случае вы получите исключение времени выполнения.

Полученный set имеет тип IQueryable<BaseEntity>, поэтому вопрос в том, насколько полезен этот результат и как вы можете применять дополнительные фильтры для своих производных сущностей, таких как Where(w => w.Name == "abc"). По крайней мере, я не смог получить компилируемый код, сделав set типа dynamic. Я также не хотел бы потерять всю строгую типизацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...