2016-07-27 4 views
0

에 DynamicLinq 사용 :엔티티 프레임 워크 : 나는 하나 개의 필터 방법으로 주로 일반 응용 프로그램 작업입니다 일반 필터 방식

{ 
    Field: "Header.Title", 
    Operator: "contains", 
    Value: "asdf" 
} 

I : 여기

IQueryable<T> Filter<T>(IQueryable<T> query, Filter filter) where T : IDataBaseEntity 

하면 필터 객체에 전달되는 다르게 처리하는 연산자 (contains, <,>, == 등)에 대한 스위치가 있지만이 예제에서는 "contains"에만 초점을 맞출 것입니다.

전달되는 "query"변수는 200 개의 모든 엔터티가 상속하는 인터페이스 인 인터페이스의 일반적인 목록입니다. 필자는이 네임 스페이스의 엔티티 유형에 액세스 할 필요조차 없습니다.

이 예제에서 "쿼리"매개 변수는 엔터티 "페이지"의 IQueryable입니다. 내 도메인이 "페이지"무엇인지 모르는, 그러나

Expression<Func<Page, bool>> exp = l => l.Contains(filter.Value); 
query = query.Where("@0(it)", exp); 

, 내 응용 프로그램의이 부분은 강력하게 형식화되지 않으며, 대신 상속 사용하고 : DynamicLinq의 전형적인 예는 다음 것이 포함 Func <> 첫 번째 유형으로 IDataBaseEntity. "IDataBaseEntity '유형에"Header "속성이나 필드가 존재하지 않으므로 예외가 발생합니다. 나는 다른 여러 가지 옵션을 시도했지만이 문제가 주요 문제로 끝났습니다.

참고 : 저는 이것을 IQueryable로 유지해야하며 성능상의 이유로 IEnumerable로 바꾸고 싶지 않습니다. 쿼리는 필터링, 정렬 및 페이징 후에 만 ​​실행됩니다 (.AsEnumerable()).

실제 엔티티 유형에 대해 알지 못하는 네임 스페이스의 인터페이스 유형으로 IQueryable에 대해 동적 linq를 실행할 수 있습니까?

답변

0

인터페이스를 전혀 사용하지 않는 방법 - 동적 인 Linq는 늦은 바운드입니다. WhereIQueryable<T>에 적용하면 결과는 IQueryable<T>이됩니다.

즉시 올바르게 문자열 술어를 구축 할 수 있습니다, 다음과 같은 작업을해야합니다 :

query = query.Where("Header.Title.Contains(@0)", filter.Value); 
+0

아 덕분에. 이것은 90 %의 정답으로 보이므로 올바른 것으로 표시하겠습니다. 이 게시물을 읽는 다른 사용자를위한 몇 가지 메모 : 아무것도 아니거나 "T : IDataBaseEntity"대신 메서드 유형을 "T : class"로 지정해야합니다. 그렇지 않으면 강력하게 형식화 된 쿼리가 있고 .OfType으로 끝내려고 시도하는 경우 () 컴파일을 통과하려면 런타임에 EF complex/primitive 예외가 발생합니다. LinqKit의 query.AsExpandable()을 사용하여 "LINQ 표현식 노드 유형 'Invoke'가 LINQ to Entities에서 지원되지 않습니다. AsExpandable의 실적이 좋지 않거나 다른 방법이있는 경우 확실하지 않습니다. –