0

나중에 linq where (Linq2NHibernate) 메서드에서 where 술어를 사용할 메소드를 생성하려고합니다. 내가 여기에있는 것은 Linq 쿼리에 사용할 식 만들기를 수행하는 메서드입니다. 의이.net NHibernate 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;    
} 

표현은 "항상 true"단순한보다 더 복잡 할 것 몇 가지 코드를 보자,하지만 난이 문제에 대해 나는 동일한 동작을 얻었다. 당신이 볼 .And은 확장 메서드 (I 진짜 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); 
    } 
} 

지금 내가 만든 식을 수집하고 DAL 관리자에 전달하는 방법과 비즈니스 로직 클래스가 있습니다. 그 방법은 단순히 당신이 내가 (경우에 당신이 문제를 의심 occour 나는 2의 발현 toghether 체인에 피도 경우) 보안 관리자에서 다른 표현을 검색 을 본 후 호출 할 수 있습니다으로

var userFilterExpression = getUserFilterExpression(filterStructure); 
var securityFilterExpression = new BL.SecurityManager().getFilterExpression<Model.FattureEmesse>(user); 
var totalFilterExpression = userFilterExpression.And(securityFilterExpression); 

호출

나는 메서드를 호출 할 때 모든 쿼리

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(); 
     } 
    } 
} 
그래서

를 만들기 위해 toghether 넣어된다

var filteredFatture = new GenericDalManager().getFilteredList<Model.FattureEmesse>(maximumRows, startRowIndex, totalFilterExpression); 

이것은입니다 쿼리를 수행하면 마지막 줄에 표시되는 .ToList() 호출에서 오류가 다시 나타납니다. 오류는 개체 참조가 개체의 인스턴스로 설정되지 않았습니다. 그리고 NHibernate.Linq에서 발생합니다. 이 문제는 And 확장 메서드와 관련이있는 것 같습니다. 왜냐하면 체인을 사용하지 않고 간단한 식을 만들면 작동하기 때문입니다. 무엇이 잘못 되었나요? genericDalManager.getFilteredList 메서드로 전달하는 식을 간단히 컴파일하면 모든 것이 작동하지만 식을 데이터베이스에서 쿼리로 평가하지 않습니다 (분명히 "항상 참"인 식은 흥미로운 where 절을 생성하지 않습니다. 하지만 좀 더 복잡한 필터를 수행하기 위해서는이 작업이 필요합니다.) 이상한 점은 getUserFiltreExpression 메서드에서 두 개의 "항상 true"식을 연결하지 않고 첫 번째 값만 반환하면 모든 것이 제대로 작동한다는 것입니다. 동일한 표현식이 BL.SecurityManager(). getFilterExpression (user) 호출의 결과로 체인화 된 경우에도 마찬가지입니다. 그런데이 문제를 테스트하기 위해이 마지막 호출이 또 다른 "항상 true"표현을 반환합니다.

누구나 도움주세요 ... 나는 화를 내고있다!

답변

1

나는 문제가 당신과 표현의 결과 (호출 후)가 아니라 표현 자체와 함께 있다고 생각합니다. 이 표현식은 아마도 구문 분석 될 수 없습니다. 당신은 또한 당신에게해야 할 수도 있습니다 And (논리 및) Andse (bitwise 및) 어쩌면 매개 변수를 rebind