Я пытаюсь создать метод, который создает предикат where для последующего использования в методе linq where (Linq2NHibernate).
у меня здесь есть метод, который выполняет создание выражения, которое будет использоваться в запросе Linq.
Давайте посмотрим код
private Expression<Func<Model.FattureEmesse, bool>> getUserFilterExpression(FattureFilter filterStructure)
{
Expression<Func<Model.FattureEmesse, bool>> dataDocumentoFilter = f =>
true;
Expression<Func<Model.FattureEmesse, bool>> dataFineValiditaFilter = f =>
true;
var userFilterExpression = dataDocumentoFilter
.And(dataFineValiditaFilter)
.And(dataImportazioneFilter);
return userFilterExpression;
}
Выражение будет более сложным, чем простое «всегда верно», но у меня возникла такая же проблема.
. И вы видите, это метод расширения (я нашел здесь на SO на самом деле)
internal static class PredicateExtensions
{
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2) where T : Model.DomainModelObject
{
InvocationExpression invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
}
}
Теперь у меня есть класс Business Logic с методом, который собирает созданное выражение и передает его менеджеру DAL.
Этот метод просто вызывает
var userFilterExpression = getUserFilterExpression(filterStructure);
var securityFilterExpression = new BL.SecurityManager().getFilterExpression<Model.FattureEmesse>(user);
var totalFilterExpression = userFilterExpression.And(securityFilterExpression);
Как вы можете видеть, я получаю другое выражение из Securitymanager (в случае, если вы сомневаетесь, проблема возникает, даже если я избегаю связывать воедино выражение 2)
а затем позвоните
var filteredFatture = new GenericDalManager().getFilteredList<Model.FattureEmesse>(maximumRows, startRowIndex, totalFilterExpression);
Здесь все помещается вместе, чтобы выполнить запрос
public class GenericDalManager
{
internal IList<T> getFilteredList<T>(int maximumRows, int startRowIndex, Expression<Func<T, bool>> expressionResult) where T : Model.DomainModelObject
{
using (var session = PersistenceManager.Istance.GetSession())
{
var items = (from o in session.Linq<T>()
orderby o.Id
select o);
var filteredItems = items.Where(expressionResult)
.Skip(startRowIndex)
.Take(maximumRows);
return filteredItems.ToList();
}
}
}
Итак, когда я вызываю метод, выполняющий запрос, он возвращает ошибку в вызове .ToList (), который вы видите в последней строке.
Ошибка
В экземпляре объекта не задана ссылка на объект.
И это происходит в NHibernate.Linq.
Кажется, что проблема связана с методом расширения And, так как он работает, если я делаю простое выражение, без какой-либо цепочки.
В чем дело?
Если я просто скомпилирую выражение перед передачей его методу genericDalManager.getFilteredList, все будет работать, но оно не будет оценивать выражение как запрос к базе данных (очевидно, выражение «всегда верно» не будет генерировать интересное предложение where, но Мне нужно, чтобы это работало, чтобы сделать более сложный фильтр).
Странно то, что если я не буду связывать два выражения «всегда истинно» в методе getUserFiltreExpression, но я верну только первое, все работает нормально. Даже если после того же выражения будет прикован результат вызова BL.SecurityManager (). GetFilterExpression (user).
И, кстати, для проверки этой проблемы этот последний вызов возвращает другое выражение «всегда истинно».
Кто-нибудь, помогите, пожалуйста ... Я злюсь!