Predicate Builder удаляет предикат на основе другого предиката

У меня есть некоторые объекты, которые имеют свойство IsDeleted (логическое удаление), и когда я делаю запросы, стандартом будет возвращать все, кроме удаленных, например:

var query = collection.Where(e=> !e.IsDeleted);

Я использую построитель предикатов для создания некоторых предикатов для повторного использования, поэтому у меня есть такой поиск:

    public static Func<FakeEntity, bool> ContainsName(string keyword) {
        var predicate = NotDeleted();
        predicate = predicate.And(e => e.Name.Contains(keyword));
        return predicate;
    }

и предикат NotDeleted():

    public static Func<FakeEntity, bool> NotDeleted() {
        var predicate = PredicateBuilderDelegate.True<FakeEntity>();
        predicate = predicate.And(e => !e.IsDeleted);
        return predicate;
    }

я хочу создать еще один предикат, который «отменяет» NotDeleted(), поэтому в коде я могу вызвать:

var result = collection.Where(FakeEntity.ContainsName("keyword")
                         .And(FakeEntity.IncludeDeleted()));

Идея заключается в том, что когда я использую ContainsName, он возвращает все объекты, содержащие эту строку, которые не были удалены, но я хочу каким-то образом явно сказать, что нужно включить эти удаленные.

Это понятно?

То, что я попробовал без везения, это:

    public static Func<FakeEntity, bool> IncludeDeleted() {
        var predicate = PredicateBuilderDelegate.True<FakeEntity>();
        predicate = predicate.And(e => e.IsDeleted);
        return predicate;
    }

person Bart Calixto    schedule 29.10.2014    source источник
comment
Логически вы никогда не получите больше результатов, добавляя предикаты.   -  person Ben Robinson    schedule 29.10.2014
comment
Ваш код разработан неправильно. Операция ContainsName должна фильтровать элементы, содержащие имя, а не элементы, содержащие имя и не удаляемые. Если вам нужны элементы, которые содержат имя и не удаляются, ваш запрос работает так, как предполагалось. Если вам нужны элементы, которые содержат имя и не удаляются, то это то, о чем вы просите.   -  person Servy    schedule 29.10.2014
comment
@BenRobinson Конечно, да. Вы используете Или, а не И. Не то, чтобы это решает эту конкретную проблему.   -  person Servy    schedule 29.10.2014
comment
К вашему сведению, ваше постоянное И-соединение одного предиката с TRUE просто бессмысленно. Вы можете просто удалить весь этот код.   -  person Servy    schedule 29.10.2014
comment
@Servy, хотя согласен, у меня будут все запросы, такие как: Где (NotDeleted(). И (ContainsName ('')) ... Я пытаюсь сохранить некоторые NotDeleted() везде.   -  person Bart Calixto    schedule 29.10.2014
comment
@Bart Тогда вам нужно иметь как ContainsName, так и IsActiveAndContainsName   -  person Servy    schedule 29.10.2014


Ответы (1)


Невозможно получить точно то, что вы хотите. Вам нужно будет сделать более значительный редизайн, чтобы это стало возможным.

По сути, если вы хотите построить предикат, вы должны просто не добавлять выражения, которые вам не нужны, вместо того, чтобы добавлять их и пытаться извлечь их позже. В вашей ситуации это означает отказ от безусловной фильтрации удаленных элементов всякий раз, когда вы хотите отфильтровать элементы, имя которых содержит значение. Выделите эти две операции, если в ваших требованиях указано, что иногда они должны быть разделены.

person Servy    schedule 29.10.2014