【问题标题】:Dynamic C# expression that Selects from given List, containing a given value从给定列表中选择的动态 C# 表达式,包含给定值
【发布时间】:2017-10-16 03:37:14
【问题描述】:

我有以下对象结构

public class Client
{
    public Client()
    {
        Identifiers = new List<ExternalIdentifier>();
    }

    public Guid? PatientId { get; set; }
    .
    .

    public IList<ExternalIdentifier> Identifiers { get; set; }
}

我想构建以下动态表达式,

Clients.Where(s=&gt;s.Identifiers.Select(a=&gt;a.Value).ToList().Contains("d"));

这是我目前所拥有的

public Expression GeneratExp(string consVal)
{
    //TODO be removed  .Where(s=>s.Identifiers.Select(a=>a.Value).ToList().Contains("d"));

    ParameterExpression externalId = Expression.Parameter(typeof(ExternalIdentifier), "id");
    Expression idProperty = Expression.PropertyOrField(externalId, "Value");

    var valueSelector = Expression.Lambda<Func<ExternalIdentifier, string>>(idProperty, new ParameterExpression[] { externalId });

    ParameterExpression client = Expression.Parameter(typeof(Models.Entities.Client), "s");
    Expression id = Expression.PropertyOrField(client, "Identifiers");

    var selM = typeof(Enumerable).GetMethods().First(x => x.Name == "Select").MakeGenericMethod(typeof(ExternalIdentifier), typeof(string));
    var selExpression = Expression.Call(null, selM, id, valueSelector);

    var toli = typeof(Enumerable).GetMethods().First(x => x.Name == "ToList").MakeGenericMethod(typeof(string));
    var toliexp = Expression.Call(null, toli, selExpression);

    var cont = typeof(Enumerable).GetMethods().First(x => x.Name == "Contains").MakeGenericMethod(typeof(string));
    var contexp = Expression.Call(null, cont, toliexp, Expression.Constant("d"));

    var retcontexp = Expression.Lambda<Func<Models.Entities.Client, bool>>(contexp, Expression.Parameter(typeof(Models.Entities.Client), "s"));

    return retcontexp; 
}

当我运行单元测试时,它会构建以下表达式 s.Identifiers.Select(a=>a.Value).ToList().Contains("d")

但是由于我没有定义“s”,所以它不会执行,非常感谢任何帮助构建以下内容。

s => s.Identifiers.Select(a=>a.Value).ToList().Contains("d") 非常感谢

提前致谢。

【问题讨论】:

    标签: .net c#-4.0 lambda expression


    【解决方案1】:

    您非常非常接近获得所需的结果。您只需要为您在定义表达式主体时使用的 Expression.Lambda&lt;TDelegate&gt; 工厂方法使用 same ParameterExpression 实例参数。将 return 之前方法的最后一行更改为:

    var retcontexp = Expression.Lambda<Func<Client, bool>>(contexp, client);
    

    ...生成的 lambda 将是有效的,您将能够编译它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-08
      • 1970-01-01
      • 2021-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      相关资源
      最近更新 更多