0

我正在使用动态 linq 来处理一些用户请求。它的设置方式是我将数据收集到 Var 数据中

var data = Project.Model.Adhoc.GetData().AsQueryable();

这基本上是从视图中选择 *

然后从那里我将遍历所有我必须过滤用户选择的选项

 foreach (Filters filter in filters.OrderBy(x=>x.strOrderNumber))
            {

连同一些检查和排列,我开始这样做

data = data.Where(filter.strFilter + FormatOperator(filter.strOperator) + "@0", filter.strValue).
                                Select(x => x).ToList().AsQueryable();

这工作得很好,但是数据源开始增长,所以我想做的是这样的:

data = data.select(get all items that were selected)然后做我的检查和排列。这将允许我只提取需要的内容,而不是整个数据源。C# 中使用 linq 完成此任务的最佳方法是什么。

前任。

datasource = {Name, Age, Race, Gender, Hair Color, Eye Color, height, weight, etc}

user selected = {Name, Age, Race, Gender}

我不想查询整个数据源,而是想将数据源限制为仅由用户立即引入的数据源,然后我可以根据它作为数据源进行过滤

4

2 回答 2

0

删除.ToList()foreach 循环中的调用。

data = data.Where()将使用 s 构建查询表达式AND。因此,在循环之后,您最终可以调用 .ToList() 来最终访问数据库。

更新

并且 .Select() 不是必需的。

data = data.Where(filter.strFilter + FormatOperator(filter.strOperator) + "@0", filter.strValue);

更新2

哦,再次阅读您的问题后,我知道您需要使用 OR 构建查询。

使用标准库有点困难。如果您不介意引入额外的依赖项,那么可以(可能)使用LinqKit完成

IQueryable<Product> SearchProducts (params string[] keywords)
{
    var predicate = PredicateBuilder.False<Product>();

    foreach (string keyword in keywords)
    {
        string temp = keyword;
        predicate = predicate.Or (p => p.Description.Contains (temp));
    }
    return dataContext.Products.Where (predicate);
}

虽然我不确定它与 Dynamic Linq 的效果如何。

否则,您将不得不手工制作表达式,最终可能看起来类似于:

public static class IQueryableExtensions
{
    public static IQueryable<T> WhereIn<T, TValue>(
        this IQueryable<T> source,
        Expression<Func<T, TValue>> propertySelector,
        IEnumerable<TValue> values)
    {
        return source.Where(GetWhereInExpression(propertySelector, values));
    }

    private static Expression<Func<T, bool>> GetWhereInExpression<T, TValue>(
        Expression<Func<T, TValue>> propertySelector, IEnumerable<TValue> values)
    {
        if (!values.Any())
            return c => false;

        ParameterExpression p = propertySelector.Parameters.Single();

        // You'll have to adjust this:
        var equals = values.Select(value => (Expression)Expression.Equal(
                propertySelector.Body, Expression.Constant(value, typeof(TValue))));

        var body = equals.Aggregate<Expression>(
                (accumulate, equal) => Expression.Or(accumulate, equal));
        return Expression.Lambda<Func<T, bool>>(body, p);
    }
}
于 2012-06-07T19:38:38.107 回答
0

看看动态 Linq

您可以针对任何 LINQ 数据提供程序使用 DynamicQuery 库(包括 LINQ to SQL、LINQ to Objects、LINQ to XML、LINQ to Entities、LINQ to SharePoint、LINQ to TerraServer 等)。动态查询库不使用语言运算符或类型安全的 lambda 扩展方法来构造您的 LINQ 查询,而是为您提供了基于字符串的扩展方法,您可以将任何字符串表达式传递到这些方法中。

于 2012-06-07T19:39:08.543 回答