2014-10-28 5 views
1

У меня есть запрос, переданный моей службе, сериализованный в набор классов. этот объект определяет условия в дереве, подобном структуре, для поддержки AND/ORing данных на бесконечную глубину. Затем я использую LinqToSQL для преобразования этого класса в SQL-запрос, однако мои условия (определенные с помощью PredicateBuilder) игнорируются!PredicateBuilder игнорируется в LinqToSQL

PredicateBuilder кажется очевидным решением, мои рекурсивные функции построить с Expression<Func<Error,bool>> вместо IQueryable<Error>, чтобы поддержать это, я итерацию по дереву рекурсивно и присоединять И/ИЛИ условия соответственно.

Я называю рекурсивный фильтр следующим образом: при отладке я вижу, как рекурсивная функция возвращает фильтры правильно - моя проблема в том, что эти условия игнорируются и не отображаются в выходном SQL (см. Ниже) может кто-нибудь предложить почему это может быть?

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

if (hasConditions) 
{ 
    results.Where(RecursiveHandleFilterExpression(query.Criteria)); 
} 

Это функция, которая добавляет предикаты

private Expression<Func<Error, bool>> RecursiveHandleFilterExpression(FilterExpression filterExpression) 
{ 
    // if anding, start with true Ors start with false 
    Expression<Func<Error, bool>> predicate; 
    if (filterExpression.FilterOperator == LogicalOperator.And) 
    { 
     predicate = PredicateBuilder.True<Error>(); 
    } 
    else 
    { 
     predicate = PredicateBuilder.False<Error>(); 
    } 

    // apply conditions 
    foreach (ConditionExpression condition in filterExpression.Conditions) 
    { 
     if (filterExpression.FilterOperator == LogicalOperator.And) 
     { 
      predicate.And(ApplyCondition(condition)); 
     } 
     else 
     { 
      predicate.Or(ApplyCondition(condition)); 
     } 
    } 

    // apply child filters 
    foreach (FilterExpression expression in filterExpression.Filters) 
    { 
     if (filterExpression.FilterOperator == LogicalOperator.And) 
     { 
      predicate.And(RecursiveHandleFilterExpression(expression)); 
     } 
     else 
     { 
      predicate.Or(RecursiveHandleFilterExpression(expression)); 
     } 
    } 

    return predicate; 
} 

сгенерированного SQL, полученные через DataContext.Log имущества, пропуская 2 запросов, передаваемых в столбце LoggedOn

SELECT [t2].[ErrorId], [t2].[OrganisationId], [t2].[Severity], [t2].[Source], [t2].[ExceptionMessage], [t2].[InnerExceptionMessage], [t2].[Details], [t2].[LoggedOn] 
FROM (
    SELECT [t1].[ErrorId], [t1].[OrganisationId], [t1].[Severity], [t1].[Source], [t1].[ExceptionMessage], [t1].[InnerExceptionMessage], [t1].[Details], [t1].[LoggedOn], [t1].[ROW_NUMBER] 
    FROM (
     SELECT ROW_NUMBER() OVER (ORDER BY [t0].[ErrorId], [t0].[OrganisationId], [t0].[Severity], [t0].[Source], [t0].[ExceptionMessage], [t0].[InnerExceptionMessage], [t0].[Details], [t0].[LoggedOn]) AS [ROW_NUMBER], [t0].[ErrorId], [t0].[OrganisationId], [t0].[Severity], [t0].[Source], [t0].[ExceptionMessage], [t0].[InnerExceptionMessage], [t0].[Details], [t0].[LoggedOn] 
     FROM [dbo].[Errors] AS [t0] 
     WHERE [t0].[OrganisationId] = @p0 
     ) AS [t1] 
    WHERE [t1].[ROW_NUMBER] BETWEEN @p1 + 1 AND @p1 + @p2 
    ) AS [t2] 
ORDER BY [t2].[ROW_NUMBER] 
-- @p0: Input UniqueIdentifier (Size = -1; Prec = 0; Scale = 0) [f311d7f3-3755-e411-940e-00155d0c0c4b] 
-- @p1: Input Int (Size = -1; Prec = 0; Scale = 0) [0] 
-- @p2: Input Int (Size = -1; Prec = 0; Scale = 0) [51] 
-- Context: SqlProvider(Sql2008) Model: AttributedMetaModel Build: 4.0.30319.17929 
+1

Я думаю, что вы только забыли назначить его для результата -> 'results = results.Where (RecursiveHandleFilterExpression (query.Criteria));' – Silvermind

ответ

3

And и Or методы не мутируют выражение. (Объекты неизменяемы.) Они возвращают выражение , которое представляет собой операцию. Вы игнорируете это возвращаемое значение в своем коде.

Смежные вопросы