C# 动态编译LINQ查询以验证字典值

C# 动态编译LINQ查询以验证字典值,c#,.net,linq,dictionary,lambda,C#,.net,Linq,Dictionary,Lambda,让我们假设我们需要查询一个实体列表,但我们不知道非常动态的条件,实体中有字典和简单字段,让这成为下一个实体地址(为了简单起见,我只留下了一个属性) 公共类地址 { #地区公众成员 /// ///额外的数据字段值 /// 公共IDictionary DataFieldValues{get;set;} 公共字符串City{get;set;} #端区 } 现在,如果我们在我得到实现时查询一个名为City的固定字段: private static Expression<Func<

让我们假设我们需要查询一个实体列表,但我们不知道非常动态的条件,实体中有字典和简单字段,让这成为下一个实体地址(为了简单起见,我只留下了一个属性)

公共类地址
{
#地区公众成员
/// 
///额外的数据字段值
/// 
公共IDictionary DataFieldValues{get;set;}
公共字符串City{get;set;}
#端区
}
现在,如果我们在我得到实现时查询一个名为City的固定字段:

   private static Expression<Func<Address, bool>> BuildLambdaForAQueryItem(string caption, string value)
        {
            ParameterExpression param = Expression.Parameter(typeof(Address), caption);
            BinaryExpression body = Expression.Equal(Expression.PropertyOrField(param, caption),
                                                     Expression.Constant(value,
                                                                         typeof(Address).GetProperty(
                                                                             caption).PropertyType));
            return Expression.Lambda<Func<Address, bool>>(body, param);
        }
private static Expression我认为您希望对两个相关谓词表达式使用(短路和)来构造表达式树的主体

var body = Expression.AndAlso(keyExists, valueCorresponds);
return Expression.Lambda<Func<Address, bool>>(body, dataFields);

但在这种情况下,这是巨大的杀伤力;我的建议是使用我的第一个样品。

你说得对,谢谢。但是我仍然不明白为什么我以前的实现没有成功
private static Expression<Func<Address, bool>> BuildLambdaForAnExtraField(PostedQueryItem queryItem)
{
    ParameterExpression dataFields = Expression.Parameter(typeof(Address), "x");
    var dictionaryExpression = Expression.PropertyOrField(dataFields, "DataFieldValues");
    var keyExists = Expression.Call(dictionaryExpression, "ContainsKey", null, Expression.Constant(queryItem.Caption));

    Expression dictionaryAccessExpr = Expression.Property(dictionaryExpression, "Item",
                                                           Expression.Constant(queryItem.Caption));
    var valueCorresponds = Expression.Equal(dictionaryAccessExpr, Expression.Constant(queryItem.Value));

    return Expression.Lambda<Func<Address, bool>>(keyExists, dataFields).And(
      Expression.Lambda<Func<Address, bool>>(valueCorresponds, dataFields));
}
var body = Expression.AndAlso(keyExists, valueCorresponds);
return Expression.Lambda<Func<Address, bool>>(body, dataFields);
return Expression.Lambda<Func<Address, bool>>(keyExists, dataFields)
                 .And(Expression.Lambda<Func<Address, bool>>(valueCorresponds, dataFields))
                 .Expand();