2013-04-01 2 views
1

동적 일반 메서드를 작성하려고했습니다. 고급 검색 메커니즘을 만들려면 다음을 수행하십시오. 나는 동적 LINQ동적 쿼리를 LINQ로 빌드

IQueryable<Table> query = ObjectContext.Table; 
if (parameters != null && parameters.Count > 0) 
{ 
    foreach (KeyValuePair<string, dynamic> keyValuePair in parameters) 
    { 
     query = query.Where(keyValuePair.Key + " == @0", new object[] { keyValuePair.Value }); 
    } 
} 

를 사용하지만이 일을 뭔가를 달성 할 수

, 나는 그래서 다른 방법 을 (함께 노력하고있어이

ClassTable.Parameters.Add("FKTable.Foo", foo); 
ClassTable.Parameters.Add("Bar", bar); 

과 같이 각 필드를로드 할 필요 이 코드가 작동합니다)

List<Table> lstTable = new List<Table>(); 
lstTable.AddRange(tableDAO.SelectWhere(
    u => this.EntityValues.Foo == u.Foo && this.EntityValues.Bar == u.Bar 
)); 
return lstTable; 

지금, 내 문제는, 내가 더 같은 것을하고 싶었다 나는이

그런 짓을하고 싶지 않았다

List<Table> lstTable = new List<Table>(); 
lstTable.AddRange(tableDAO.SelectWhere(
    u => !string.IsNullOrEmpty(this.EntityValues.Foo) ? this.EntityValues.Foo == u.Foo : false 
    && 
    this.EntityValues.Bar != 0 ? this.EntityValues.Bar == u.Bar : false 
)); 
return lstTable; 

(이 코드는 첫 번째 쿼리의 결과를 가져온다)

IQueryable<Data.Story> query = ctx.DataContext.Stories; 

if (criteria.StoryId != null) // StoryId 
    query = query.Where(row => row.StoryId == criteria.StoryId); 

if (criteria.CustomerId != null) // CustomerId 
    query = query.Where(row => row.Project.CustomerId == criteria.CustomerId); 

if (criteria.SortBy != null) // SortBy 
    query = query.OrderBy(criteria.SortBy + " " + criteria.SortOrder.Value.ToStringForSql()); 

내 질문이 다소 혼란 스럽다는 것을 알고 있으며 수정 및 의견을 제공하여 수정하도록하겠습니다. 바로 알려주세요.


TL; 동적 쿼리를 만드는 데 도움이 필요합니다. 여기서는 검색에 사용되는 매개 변수 만 전달하면됩니다. 따라서 사용자에게 고급 검색 옵션을 만들 수 있습니다.

public static IQueryable<T> Where<T>(this IQueryable<T> source, string propertyOrFieldName, object value) 
{ 
    var param = Expression.Parameter(typeof(T), "x"); 
    var prop = Expression.Property(param, name); 
    var @const = Expression.Constant(value, prop.Type); 
    var equals = Expression.Equal(prop, @const); 
    var lambda = Expression.Lambda(equals, param); 
    return source.Where(lambda); 
} 

foreach(var p in parameters) 
{ 
    query = query.Where(p.Key, p.Value); 
} 
+1

이게 당신이 찾고 있는게 있나요? [동적 LINQ] (http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx) 또는 [ Predicate Builder] (http://www.albahari.com/nutshell/predicatebuilder.aspx)? – jrummell

+0

@jrummell 네, 두 주제에서 모두 독서를하고있었습니다. 감사합니다 +1 –

답변

2

당신은 Expression 년대를 직접 작성할 수 있습니다.

내 DAO 클래스에서 두 가지 메서드를 만듭니다. 첫 번째는 표현식 목록을로드하고 두 번째에서는 읽은 다음 실행합니다.

public List<System.Linq.Expressions.Expression<Func<E, bool>>> whereList = new List<Expression<Func<E, bool>>>(); 
public List<E> ExecuteSelectFilter() 
{ 
    System.Linq.Expressions.Expression<Func<E, bool>> whereFinal = c => true; 

    foreach (System.Linq.Expressions.Expression<Func<E, bool>> whereItem in whereList) 
    { 
     if (whereItem != null) 
     { 
      var invokedExpr = Expression.Invoke(whereFinal, whereItem.Parameters.Cast<Expression>()); 

      whereFinal = Expression.Lambda<Func<E, bool>> 
        (Expression.AndAlso(whereItem.Body, invokedExpr), whereItem.Parameters); 
     } 
    } 
    return this.ObjectContext.CreateQuery<E>(EntitySetName).Where(whereFinal.Compile()).ToList(); 
} 

내 DAO에 전화를 그 방법은, 그래서 내가 가지고있는 비즈니스 클래스에서 액세스 할 수 있습니다. 그것은 나를 도와 같은

tableDAO.whereList.Clear(); 

#region Filters 
// Foo 
if (!String.IsNullOrEmpty(this.entityValues.Foo)) 
    tableDAO.whereList.Add(q => q.Foo.Contains(this.entityValues.Foo)); 
// Bar 
if (this.entityValues.Bar > 0) 
    tableDAO.whereList.Add(q => q.Bar== this.entityValues.Bar); 
#endregion 

return tableDAO.ExecuteSelectFilter(); 

희망이 도움이 누군가.

+0

나는 이것을 시도했다. 내가 바라던대로 일하지 않았습니까? /하지만 훌륭한 대답입니다. +1 –

관련 문제