2010-03-09 4 views
3

특성 다음 받기 술어 내가 닮은 인터페이스를 가지고 정보

public IEnumerable<IDocument> Search(Predicate<IDocument> predicate) { ... } 

을 IDocument는 다음과 같습니다 여기서

내가 분해 할 문서 바이더의 구현에 대한 생각
public interface IDocument 
{ 
    string Id {get; set;} 
    string Title {get; set;} 
    ... 
} 

우리가 현재 OR/M 매핑을 가지고 있지 않은 문서 데이터베이스에 대한 SQL 문자열을 만들기 위해 Predicate의 내용을 추출하고 속성을 추출합니다. 예 : 사용자가 ID 또는 제목으로 검색 중인지 알고 싶습니다. 따라서 ID로 검색하거나 제목에서 LIKE 검색을 수행해야하는지 알 수 있습니다.

저는 항상 LINQ를 많이 사용했지만 파이프 라인의 다른 끝에 앉아있는 것은 이번이 처음입니다 ... 표현 트리 및 리플렉션에서 약간 읽었지만 조각이 떨어지지 않았습니다. 아직 자리에 있습니다. 어떻게하면 (?) 술어를 분해/반영하여 SQL 문자열로 연결할 수있는 매개 변수 목록을 얻을 수 있습니까? 나는이 거친 스케치 같은 뭔가를 찾고 있어요 :

public IEnumerable<IDocument> Search(Predicate<IDocument> predicate) 
{ 
    string id = DoSomeMagic(predicate, "Id"); 
    string title = DoSomeMagic(predicate, "Title"); 
    if (!string.isNullOrEmpty(id)) 
     ...make ID search 
    else 
     ...search by title 
} 

면책 조항 : 공급자 인라인 SQL에게 올바른 선택을하게 올 가을 교체 행 사내 레거시 시스템에 대한; O)

답변

1

쉽게 술어를 성찰 할 수 없다. 어쩌면 당신은 좀 더 특별 조건 타입으로 설계를 변경보다 구체적인 조건 인터페이스를 고려해야합니다

public interface IDocument 
    { 
     string Id {get; set;} 
     string Title {get; set;} 
    } 
    public class SearchCriteria 
    { 
     public Nullable<int> Id; 
     public string Title; 
    } 
    public IEnumerable<IDocument> Search(SearchCriteria predicate) 
    { 
     if (predicate.Id.HasValue) 
      //...make ID search 
     else if (!string.IsNullOrEmpty(predicate.Title)) 
      //...search by title 
     else 
      // other kind of search 
    } 

이 속성을 public 필드를 교체 SearchCriteria에서 검색 로직을 넣어 (예 .GetResult() 또는. GetSQLQuery()) 이것은 사용 가능한 모든 검색 기준을 알 수 있다고 가정하고 시스템에 적합 할 수 있습니다.

+0

를 호출하여 식을 실행할 수 있습니다

void Main() { show(x=>x.Length==5); } void show(Expression<Predicate<string>> e){ e.Dump(); } 

(LinqPad가 정말 잘 발현을 시각화 덤프 확장 방법을 제공합니다) LinqPad에서 다음을 실행 해보십시오 할 것. 우리가 구축해야하는 표현식 트리가 극도로 복잡해져서 술어에 반대하고 더 많은 KISS 접근법을 사용합니다. – kerbou

3

당신은 할 수 없습니다 술어 또는 위임자와 함께이 작업을 수행하십시오. 그것들은 컴파일되고 그것이 무엇을하는지에 대한 정보를 얻을 수 없습니다. 이 경우 실제로는 Expression 개의 나무가 필요하지만이를 직접 파싱하는 것은 어려울 수 있습니다. O/RM 도구를 사용하는 것이 좋습니다.

당신은 바람이 될 것입니다 검색 방법을 구축, 예를 들어 SQL로 LINQ와 함께 표현을 사용

public IEnumerable<Document> Search(
    Expression<Func<Document, bool>> predicate) 
{ 
    using (db = new DocumentDataContext()) 
    { 
     return db.Documents.Where(predicate).ToArray(); 
    } 
} 
0

대신 표현식>을 수락하는 것으로 메소드를 선언해야합니다. 이 표현식은 (비록 그것이 될 수있는 많은 다른 것들이 있지만) 내성적 일 수 있습니다.

당신은 우리가 결정했습니다 무엇 그 Compile