English 中文(简体)
我如何把准则的表述结合起来?
原标题:How do I combine LINQ expressions into one?
  • 时间:2009-12-17 15:27:13
  •  标签:
  • linq

我用多种领域(公司名称、邮政编码等)填写表格,使用户可以在数据库中搜寻公司。 如果用户在不止一个领域进入价值,那么我需要寻找所有这些领域。 我正在利用LINQ查询数据库。

迄今为止,我已设法写出一份职能,其中将审视他们的投入,并把它变成一份表述清单。 我现在要把这份名单变成一个单一的表述,然后我可以通过林研中心供应商执行。

我的初步尝试如下:

private Expression<Func<Company, bool>> Combine(IList<Expression<Func<Company, bool>>> expressions)
    {
        if (expressions.Count == 0)
        {
            return null;
        }
        if (expressions.Count == 1)
        {
            return expressions[0];
        }
        Expression<Func<Company, bool>> combined = expressions[0];
        expressions.Skip(1).ToList().ForEach(expr => combined = Expression.And(combined, expr));
        return combined;
    }

然而,这只是一个例外的信息,即“双轨操作者,没有为......定义”。 是否有任何想法需要把这些表达结合起来?

EDIT:更正了我忘掉的一条线,把表达结果和表达方式加在一起变成一个变量。 感谢指出这一点。

最佳回答

EDIT:Jason的回答现在比在表达树脂方面的回答更充分,因此我删除了这个轨道。 然而,我要离开:

我假设你重新使用这些代码。 什么是条? 这应具有同样的效力:

var query = ...;
foreach (var condition in conditions)
{
    query = query.Where(condition);
}
问题回答

您可使用http://msdn.microsoft.com/en-us/library/bb548651.aspx” rel=“noretinger”E amountable.Aggregate , 加上。 此处为通用文本:

Expression<Func<T, bool>> AndAll<T>(
    IEnumerable<Expression<Func<T, bool>>> expressions) {

    if(expressions == null) {
        throw new ArgumentNullException("expressions");
    }
    if(expressions.Count() == 0) {
        return t => true;
    }
    Type delegateType = typeof(Func<,>)
                            .GetGenericTypeDefinition()
                            .MakeGenericType(new[] {
                                typeof(T),
                                typeof(bool) 
                            }
                        );
    var combined = expressions
                       .Cast<Expression>()
                       .Aggregate((e1, e2) => Expression.AndAlso(e1, e2));
    return (Expression<Func<T,bool>>)Expression.Lambda(delegateType, combined);
}

页: 1

expr => Expression.And(combined, expr);

新的<代码>Expression是双向和combinedexpr的结果,但并非互换的combined

在这方面,我们有一个关于将林克表达方式结合起来的一般性问题。 我对这个问题有一个普遍的解决办法。 我将回答所存在的具体问题,尽管如此,这肯定不是去做。 但是,如果简单的解决办法在你看来失败,你可能会尝试采用这种办法。

首先,需要一个由两个简单功能组成的图书馆。 它们使用<代码>System.Linq.Expressions.ExpressionVisitor,积极修改表述。 关键特征是统一表述中的参数,使同一名称的2个参数相同()。 统一参数ByName。 其余部分用特定表述(ReplacePar)替换一个标明的参数。 图书馆有麻醉物品许可证:LinqExprHelper,但你可能很快自行撰写文章。

图书馆允许将复杂表述结合起来的简便的辛迪加。 你们可以将乐于读的lam语与能动的表达和构成混在一起,而这种表达力非常强。

    private static Expression<Func<Company, bool>> Combine(IList<Expression<Func<Company, bool>>> expressions)
    {
        if (expressions.Count == 0)
        {
            return null;
        }

        // Prepare a master expression, used to combine other
        // expressions. It needs more input parameters, they will
        // be reduced later.
        // There is a small inconvenience here: you have to use
        // the same name "c" for the parameter in your input
        // expressions. But it may be all done in a smarter way.
        Expression <Func<Company, bool, bool, bool>> combiningExpr =
            (c, expr1, expr2) => expr1 && expr2;

        LambdaExpression combined = expressions[0];
        foreach (var expr in expressions.Skip(1))
        {
            // ReplacePar comes from the library, it s an extension
            // requiring `using LinqExprHelper`.
            combined = combiningExpr
                .ReplacePar("expr1", combined.Body)
                .ReplacePar("expr2", expr.Body);
        }
        return (Expression<Func<Company, bool>>)combined;
    }

认为你有两种表述,即1和2,你可以尝试:

var combineBody = Expression.AndAlso(e1.Body, Expression.Invoke(e2, e1.Parameters[0]));
var finalExpression = Expression.Lambda<Func<TestClass, bool>>(combineBody, e1.Parameters).Compile();




相关问题
IEnumerable to array of parameter

Using linq? and XML is there a way to convert this IEnumerable to a string array of the value parameter? List<string> idList = new List<string>(); foreach (XElement idElement in word....

linq query for tag system - search for multiple tags

I have two tables, Tags(tagid, postid, tagname) and posts(postid, name, ...) now i want to make a query that returns me all posts that have a generic amount of tags. like: i want all posts that have ...

Linq operations against a List of Hashtables?

I m working with a set of legacy DAO code that returns an IList, where each Hashtable represents the row of a dynamically executed SQL query. For example, the List might contain the following records/...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

How to filter duplicate list items

i have list of items IList with data that looks list this: GenId TestMode 1 0 1 1 3 0 3 1 4 NULL 2 NULL i want to remove the index ...

C# Grouping/Sorting a Generic List<> using LINQ

Im looking to group and sort a Generic List<>. I have a list of objects representing files and each of these objects has a FileName, FileType and FileDate property. FileType is defined as an ...

热门标签