包含不工作的 Lambda 表达式
Lambda Expression With Contains Not Working
我是 Lambda 表达式的新手,在获取我想要的输出时遇到了一些问题。更具体地说,我无法让 LINQ 包含 Lambda 表达式的一部分正确。
这是我目前的情况:
// The following line is what I want for my Final Result
var distinctValues = db.Equipment.Where(m => m.Model != null && m.Model.Contains(SearchTerm)).Select(m => m.Model).Distinct().ToList();
var queryableData = db.Equipment.AsQueryable();
var parameterExpression = Expression.Parameter(typeof(Equipment), Column);
var constant = Expression.Constant(null);
var property = Expression.Property(parameterExpression, Column);
var expression1 = Expression.NotEqual(property, constant);
var expression2 = Expression.Equal(property,constant);
Expression callContains = Expression.Call(typeof(Queryable), "Contains", new[] { <string> } );
var lambda1 = Expression.Lambda<Func<Equipment, bool>>(expression1, parameterExpression);
var lambda2 = Expression.Lambda<Func<Equipment, string>>(property, parameterExpression);
var lambda3 = Expression.Lambda<Func<Equipment, bool>>(callContains, parameterExpression);
var compiledLambda1 = lambda1.Compile();
var compiledLambda2 = lambda2.Compile();
我正在传递任何 属性 和一个搜索词,我想生成与上面的 LINQ 查询等效的以 "var distinctValues" 开头的 Lambda 表达式。我在处理以 "Expression callContains" 开头的行时遇到问题。
非常感谢任何帮助。
谢谢,
皮特
Contains
是 string.Contains
。所以,给定:
static readonly MethodInfo contains = (from x in typeof(string).GetMethods(BindingFlags.Instance | BindingFlags.Public)
where x.Name == nameof(string.Contains) && !x.IsGenericMethod
let pars = x.GetParameters()
where pars.Length == 1 &&
pars[0].ParameterType == typeof(string)
select x).Single();
那么 .Where()
表达式树是:
// m =>
var parameterExpression = Expression.Parameter(typeof(Equipment), "m");
// m.Model
var modelProperty = Expression.Property(parameterExpression, nameof(Equipment.Model));
// m.Model != null
var nonNullExpression = Expression.NotEqual(modelProperty, Expression.Constant(null, typeof(string)));
// SearchTerm
var searchTermConstant = Expression.Constant(SearchTerm);
// m.Model.Contains(SearchTerm)
var containsExpression = Expression.Call(modelProperty, contains, searchTermConstant);
// m.Model != null && m.Model.Contains(SearchTerm)
var andExpression = Expression.AndAlso(nonNullExpression, containsExpression);
// m => ...
var lambda = Expression.Lambda<Func<Equipment, bool>>(andExpression, parameterExpression);
谢谢 Xanatos。在您的帮助下,我能够解决我的问题。这是我想出的最终解决方案。只是一些小改动:
// m =>
var parameterExpression = Expression.Parameter(typeof(Equipment), "m");
// m.Model
var modelProperty = Expression.Property(parameterExpression, Column);
// m.Model != null
var nonNullExpression = Expression.NotEqual(modelProperty, Expression.Constant(null, typeof(string)));
// SearchTerm
var searchTermConstant = Expression.Constant(SearchTerm);
// m.Model.Contains(SearchTerm)
var containsExpression = Expression.Call(modelProperty, "contains", null, searchTermConstant);
// m.Model != null && m.Model.Contains(SearchTerm)
var andExpression = Expression.AndAlso(nonNullExpression, containsExpression);
var lambda1 = Expression.Lambda<Func<Equipment, string>>(modelProperty, parameterExpression);
var lambda2 = Expression.Lambda<Func<Equipment, bool>>(andExpression, parameterExpression);
var compiledLambda1 = lambda1.Compile();
var compiledLambda2 = lambda2.Compile();
var distinctValues1 = db.Equipment.Where(compiledLambda2).Select(compiledLambda1).Distinct().ToList();
首先,我对 containsExpression 使用了不同的重载。其次,我想要模型 属性 作为参数。基本上,我想传入一个变量 属性 (列)和变量 searchterm。就是这样。
我是 Lambda 表达式的新手,在获取我想要的输出时遇到了一些问题。更具体地说,我无法让 LINQ 包含 Lambda 表达式的一部分正确。
这是我目前的情况:
// The following line is what I want for my Final Result
var distinctValues = db.Equipment.Where(m => m.Model != null && m.Model.Contains(SearchTerm)).Select(m => m.Model).Distinct().ToList();
var queryableData = db.Equipment.AsQueryable();
var parameterExpression = Expression.Parameter(typeof(Equipment), Column);
var constant = Expression.Constant(null);
var property = Expression.Property(parameterExpression, Column);
var expression1 = Expression.NotEqual(property, constant);
var expression2 = Expression.Equal(property,constant);
Expression callContains = Expression.Call(typeof(Queryable), "Contains", new[] { <string> } );
var lambda1 = Expression.Lambda<Func<Equipment, bool>>(expression1, parameterExpression);
var lambda2 = Expression.Lambda<Func<Equipment, string>>(property, parameterExpression);
var lambda3 = Expression.Lambda<Func<Equipment, bool>>(callContains, parameterExpression);
var compiledLambda1 = lambda1.Compile();
var compiledLambda2 = lambda2.Compile();
我正在传递任何 属性 和一个搜索词,我想生成与上面的 LINQ 查询等效的以 "var distinctValues" 开头的 Lambda 表达式。我在处理以 "Expression callContains" 开头的行时遇到问题。
非常感谢任何帮助。
谢谢,
皮特
Contains
是 string.Contains
。所以,给定:
static readonly MethodInfo contains = (from x in typeof(string).GetMethods(BindingFlags.Instance | BindingFlags.Public)
where x.Name == nameof(string.Contains) && !x.IsGenericMethod
let pars = x.GetParameters()
where pars.Length == 1 &&
pars[0].ParameterType == typeof(string)
select x).Single();
那么 .Where()
表达式树是:
// m =>
var parameterExpression = Expression.Parameter(typeof(Equipment), "m");
// m.Model
var modelProperty = Expression.Property(parameterExpression, nameof(Equipment.Model));
// m.Model != null
var nonNullExpression = Expression.NotEqual(modelProperty, Expression.Constant(null, typeof(string)));
// SearchTerm
var searchTermConstant = Expression.Constant(SearchTerm);
// m.Model.Contains(SearchTerm)
var containsExpression = Expression.Call(modelProperty, contains, searchTermConstant);
// m.Model != null && m.Model.Contains(SearchTerm)
var andExpression = Expression.AndAlso(nonNullExpression, containsExpression);
// m => ...
var lambda = Expression.Lambda<Func<Equipment, bool>>(andExpression, parameterExpression);
谢谢 Xanatos。在您的帮助下,我能够解决我的问题。这是我想出的最终解决方案。只是一些小改动:
// m =>
var parameterExpression = Expression.Parameter(typeof(Equipment), "m");
// m.Model
var modelProperty = Expression.Property(parameterExpression, Column);
// m.Model != null
var nonNullExpression = Expression.NotEqual(modelProperty, Expression.Constant(null, typeof(string)));
// SearchTerm
var searchTermConstant = Expression.Constant(SearchTerm);
// m.Model.Contains(SearchTerm)
var containsExpression = Expression.Call(modelProperty, "contains", null, searchTermConstant);
// m.Model != null && m.Model.Contains(SearchTerm)
var andExpression = Expression.AndAlso(nonNullExpression, containsExpression);
var lambda1 = Expression.Lambda<Func<Equipment, string>>(modelProperty, parameterExpression);
var lambda2 = Expression.Lambda<Func<Equipment, bool>>(andExpression, parameterExpression);
var compiledLambda1 = lambda1.Compile();
var compiledLambda2 = lambda2.Compile();
var distinctValues1 = db.Equipment.Where(compiledLambda2).Select(compiledLambda1).Distinct().ToList();
首先,我对 containsExpression 使用了不同的重载。其次,我想要模型 属性 作为参数。基本上,我想传入一个变量 属性 (列)和变量 searchterm。就是这样。