объединить два выражения - PullRequest
1 голос
/ 02 мая 2011

Я пытаюсь создать выражение для использования в запросе структуры объекта. Я создал два выражения:

public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(long additionId)
    {
        return x => x.PriceDefinition.AdditionsPrices.Any(a => a.AdditionId == additionId);
    }
public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
    long? inviterId, long? routeId, long? luggageTypeId)
{
    return x =>
        (inviterId.HasValue || routeId.HasValue || luggageTypeId.HasValue) &&
        !(
            (x.PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
                PriceDefinition.InviterId.Value != inviterId.Value) ||

            (PriceDefinition.LuggageTypeId.HasValue && luggageTypeId.HasValue &&
                PriceDefinition.LuggageTypeId.Value != luggageTypeId.Value) ||

            (PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
                PriceDefinition.InviterId.Value != inviterId.Value)
        );
}

А теперь я хочу их объединить:

    public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
        long? inviterId, long? routeId, long? luggageTypeId, long additionId)
    {
        return IsMatchExpression(inviterId, routeId, luggageTypeId) &&
                IsMatchExpression(additionId);
    }

Этот метод не компилируется. У меня также есть чувство, что я сделал что-то не так Как я могу это исправить?

EDIT:
Я забыл бессмысленную часть! вопрос обновлен.

Ответы [ 3 ]

1 голос
/ 04 мая 2011

Вам придется работать с компонентами выражения напрямую, чтобы сделать это.

public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
        long? inviterId, long? routeId, long? luggageTypeId, long additionId)
{
    var a = IsMatchExpression(inviterId, routeId, luggageTypeId);
    var b = IsMatchExpression(additionId);
    var p = Expression.Parameter(typeof(IEntityPriceDefinition),"x");
    var c = Expression.AndAlso(Expression.Invoke(a,p),Expression.Invoke(b,p));
    var r = Expression.Lambda<Func<IEntityPriceDefinition, bool>>(c,p);
    return r;
}

Это можно сделать более сложным, выделив .Body из каждого из двух выражений и заменив (используя ExpressionVisitor) параметры новым параметром; и каждый из двух ваших рабочих методов может быть изменен, чтобы связать их параметры в ConstantExpression s, полностью потеряв синтаксис лямбда-выражения. Эти изменения могут на самом деле быть необходимыми для создания выражения, которое может работать должным образом со структурой сущностей, но мне потребуется некоторое время, чтобы выработать пост в ответе.

См. Также Как составить запрос Entity Framework из небольших, повторно используемых запросов?

0 голосов
/ 04 мая 2011

Только что созданный комбинированный метод:

   public Expression<Func<IEntityPriceDefinition, bool>> IsMatchExpression(
        long? inviterId, long? routeId, long? luggageTypeId, long additionId)
    {
    return x =>
        (inviterId.HasValue || routeId.HasValue || luggageTypeId.HasValue) &&
        (x.PriceDefinition.AdditionsPrices.Any(a => a.AdditionId == additionId)) &&
        !(
            (x.PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
                PriceDefinition.InviterId.Value != inviterId.Value) ||

            (PriceDefinition.LuggageTypeId.HasValue && luggageTypeId.HasValue &&
                PriceDefinition.LuggageTypeId.Value != luggageTypeId.Value) ||

            (PriceDefinition.InviterId.HasValue && inviterId.HasValue &&
                PriceDefinition.InviterId.Value != inviterId.Value)
        );
}

Не лучшее решение, но оно работает.

0 голосов
/ 02 мая 2011

хорошо, это может быть что-то вроде

var x = IsMatchExpression(inviterId, routeId, luggageTypeId)
var y = IsMatchExpression(additionId);
return arg => x(arg) && y(arg) 

?

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