C#Dynamic linq包含带参数的方法

时间:2014-05-13 16:46:15

标签: c# linq dynamic

我试着像这样编写动态 linq:

public struct MyStruct
{
    public string name;
    public List<string> list;
}

void sth()
{
    List<string> _aim = new List<string>();

    List<MyStruct> _source = new List<MyStruct>();

    _source.Where(it => _aim.Contains(it.name));
}

但是我对带参数的contains方法有问题。任何人都知道如何以简单和通用的方式做到这一点? 通过功能链接:

public static IQuerable<T> Sths(this IQuerable<T> source, IQuerable<string> aim, string columnName)

其中name在columnName中,source是通用的,aim是字符串列表。

1 个答案:

答案 0 :(得分:0)

为此,我们可以编写一个表达式,该表达式将属性的值作为参数,并使用它来执行Contains检查,作为构建该部分的一个简单方法。表达。之后,我们可以用表达式替换该表达式主体中的参数,该表达式从表示源中项目的参数访问属性值,然后使用该主体构建lambda。

public static IQueryable<T> ProjectionIsIn<T>(
    this IQueryable<T> source,
    IQueryable<string> collection,
    string columnName)
{
    var param = Expression.Parameter(typeof(T));

    Expression<Func<string, bool>> containsExpression =
        s => collection.Contains(s);

    var predicateBody = containsExpression.Body.Replace(
                containsExpression.Parameters[0],
                Expression.Property(param, columnName));
    Expression<Func<T, bool>> predicate =
        Expression.Lambda<Func<T, bool>>(predicateBody, param);
    return source.Where(predicate);
}

以下方法用于将一个表达式的所有实例替换为另一个:

public static Expression Replace(this Expression expression,
    Expression searchEx, Expression replaceEx)
{
    return new ReplaceVisitor(searchEx, replaceEx).Visit(expression);
}
internal class ReplaceVisitor : ExpressionVisitor
{
    private readonly Expression from, to;
    public ReplaceVisitor(Expression from, Expression to)
    {
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node)
    {
        return node == from ? to : base.Visit(node);
    }
}