Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用LINQ构建动态查询_C#_Linq - Fatal编程技术网

C# 使用LINQ构建动态查询

C# 使用LINQ构建动态查询,c#,linq,C#,Linq,我试图构建一个动态的泛型方法。创建高级搜索机制 我可以使用动态LINQ实现一些功能 IQueryable<Table> query = ObjectContext.Table; if (parameters != null && parameters.Count > 0) { foreach (KeyValuePair<string, dynamic> keyValuePair in parameters) { que

我试图构建一个动态的泛型方法。创建高级搜索机制

我可以使用动态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 });
    }
}
因此,我正在尝试其他方法(此代码有效)

List lstTable=newlist();
lstable.AddRange(tableDAO.SelectWhere(
u=>this.EntityValues.Foo==u.Foo&&this.EntityValues.Bar==u.Bar
));
返回表;
现在,我的问题是,我想做一些更像(这段代码只带来第一次查询的结果)

List lstTable=newlist();
lstable.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
));
返回表;
我不想做这样的事

ClassTable.Parameters.Add("FKTable.Foo", foo);
ClassTable.Parameters.Add("Bar", bar);
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());
IQueryable query=ctx.DataContext.Stories;
if(criteria.StoryId!=null)//StoryId
query=query.Where(row=>row.StoryId==criteria.StoryId);
如果(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);
}
公共静态IQueryable Where(此IQueryable源、字符串属性或字段名、对象值)
{
var param=表达式参数(类型(T),“x”);
var prop=Expression.Property(参数,名称);
var@const=Expression.Constant(值,属性类型);
var等于=表达式.Equal(prop,@const);
var lambda=表达式.lambda(等于,参数);
返回源。其中(λ);
}
foreach(参数中的var p)
{
query=query.Where(p.Key,p.Value);
}
比如,我必须自己做,但我做的和他建议的有点不同

我在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();
}

希望这能帮助别人,就像它帮助了我一样。

这就是你要找的吗?或者可能?@jrummell是的,我读了这两个主题,非常好。谢谢+1我试过这个。没有如我所愿工作,但这是一个很好的答案+1.
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);
}
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();
}
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();