У меня есть запрос, переданный моей службе, сериализованный в набор классов. этот объект определяет условия в дереве, подобном структуре, для поддержки 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
Я думаю, что вы только забыли назначить его для результата -> 'results = results.Where (RecursiveHandleFilterExpression (query.Criteria));' – Silvermind