2009-12-18 1 views
1

나는 linq to sql을 사용하여 일반 검색 창을 만들길 원합니다.동적 내장 된 Linq to SQL 쿼리

class SearchWindow<T> : Form : Where T: class 
{ 
    public SearchWindow(Func<T, string> codeSelector, 
         Func<T, string> nameSelector) 
    { 
     var db = new DataContext(); 
     var table = db.GetTable<T>(); 
     var query = from item in table where 
         codeSelector(item).Contains(someText) && 
         nameSelector(item).Contains(someOtherText) 
        select item; 
    } 
} 

을 그리고 내가 그것을 좋아 사용하려고했다 :

내가 일을하려고 한 것입니다

var searchWindow = new SearchWindow<SomeTable>(x => x.CodeColumn, 
               y => y.NameColumn).Show(); 

버드 saddly 작동하지 않는, 그래서 식 트리에 대해 읽어 나는 그들과 함께 그렇게했는데, 내가 가지고 :

0 :

public SearchWindow(codeColumn, nameColumn) 
{ 
    Table<T> table = db.GetTable<T>(); 
    var instanceParameter = Expression.Parameter(typeof(T), "instance"); 
    var methodInfo = typeof(string).GetMethod("Contains", 
               new Type[] { typeof(string) }); 
    var codigoExpression = Expression.Call(Expression.Property(instanceParameter, 
               codeColumn), 
              methodInfo, 
              Expression.Constant("someText", 
               typeof(string))); 
    var nombreExpression = Expression.Call(Expression.Property(instanceParameter, 
               nameColumn), 
              methodInfo, 
              Expression.Constant("someOtherText", 
               typeof(string))); 
    var predicate = Expression.Lambda<Func<T, bool>>(
     Expression.And(codigoExpression, nombreExpression), instanceParameter); 
    var query = table.Where(predicate); 
} 

그리고 내가 할 필요가 그것을 사용하는

그러나 문자열로 열 이름을 입력해야하는 방식이 마음에 들지 않지만 intellisense 및 strong typing을 사용하기 위해 내 첫 번째 접근 방식과 비슷한 방식으로이를 수행 할 수있는 방법이 있습니다. ?

도움 주셔서 감사합니다.

+0

누락 된 부분은 "Expression.Invoke"및 "Expression.AndAlso"라고 생각합니다. 나는 한 가지 예를 보여 주려고 노력했다. –

답변

2

테스트되지 않은,하지만 뭔가 같은 :

static IQueryable<T> Search<T>(
     IQueryable<T> source, 
     Expression<Func<T, string>> codeSelector, 
     Expression<Func<T, string>> nameSelector, 
     string code, string name) 
    { 

     var row = Expression.Parameter(typeof(T), "row"); 
     var body = Expression.AndAlso(
      Expression.Call(
       Expression.Invoke(codeSelector, row), 
       "Contains", null, 
       Expression.Constant(code, typeof(string))), 
      Expression.Call(
       Expression.Invoke(nameSelector, row), 
       "Contains", null, 
       Expression.Constant(name, typeof(string)))); 
     var lambda = Expression.Lambda<Func<T, bool>>(body, row); 
     return source.Where(lambda); 
    } 

당신은 source 같은 테이블 (GetTable<T>)을 전달하고, 람다는 열 (x => x.CodeColumn/y => y.NameColumn 등)을 나타냅니다.


업데이트; LINQ - - 객체에 대한 테스트, 나는 그것뿐만 아니라 LINQ - 투 - SQL에서 작동합니다 희망 해요 :

 var data = new[] { 
      new { Code = "abc", Name = "def"}, 
      new { Code = "bcd", Name = "efg"}, 
      new { Code = "ghi", Name = "jkl"} 
     }.AsQueryable(); 

     var filtered = Search(data, x => x.Code, x => x.Name, "b", "f"); 
     var arr = filtered.ToArray(); 
+0

작동합니다!, 고맙습니다. – albertein