使用LINQ构建动态查询
问题描述:
我试图构建一个动态泛型方法。创建高级搜索机制。使用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; DR;我需要帮助来创建一个动态查询,我只需要传递在搜索中使用的参数。所以我可以为用户创建一个高级搜索选项。
答
像p.s.w.g suggested in his answer,我不得不这样做我自己,但我确实从他的提议有点不同。
我在我的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();
希望这有助于某人,就像它帮助了我。
答
你可以自己编写Expression
的:
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);
}
+0
我试过这个。没有按我的意愿= /但这是一个很好的答案。 +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
@ jrummell是的,我正在阅读这两个主题,伟大的顺便说一句。谢谢+1 –