我有这个对象
public class Ledger
{
public string fund {get;set;}
public string location {get;set;}
public string costCenter {get;set;}
public string objects {get;set;}
}
我正在使用此过滤器选项,这意味着每个值都可以为null或可以填充。在SQL中,查询看起来像是
SELECT FROM GlAccts WHERE fund = "10" AND location = "1" AND objects = "45"
SELECT FROM GlAccts WHERE objects = "45"
SELECT FROM GlAccts WHERE location = "1" AND objects = "45"
我正在尝试将其转换为linq,我遇到了一个表达式树,听起来不错,但确实有一些问题,
这是我目前拥有的。
// filtersObject, is my object which would contains fund,location,costCenter,object, just to note it is currently in a foreach (var filtersObjects) since I plan to have multiple filter objects but i am not worry about this section.
// my active list right now is List<glUserAccess> but I dont know where to apply this
ParameterExpression pe = Expression.Parameter(typeof(GlAccts), "glAccts");
Expression e1 = null;
Expression e2 = null;
Expression e3 = null;
Expression e4 = null;
// Fund EQ ""
if (!string.IsNullOrEmpty(filtersObject.fund)) {
Expression left = Expression.Property(pe, typeof(string).GetProperty("fund")); ;
Expression right = Expression.Constant(filtersObject.fund, typeof(string));
e1 = Expression.Equal(left, right);
}
// Location EQ ""
if (!string.IsNullOrEmpty(filtersObject.location)) {
Expression left = Expression.Property(pe, typeof(string).GetProperty("location")); ;
Expression right = Expression.Constant(filtersObject.location, typeof(string));
e2 = Expression.Equal(left, right);
}
// Cost Center EQ ""
if (!string.IsNullOrEmpty(filtersObject.costCenter)) {
Expression left = Expression.Property(pe, typeof(string).GetProperty("costCenter")); ;
Expression right = Expression.Constant(filtersObject.costCenter, typeof(string));
e3 = Expression.Equal(left, right);
}
// Objects EQ ""
if (!string.IsNullOrEmpty(filtersObject.objects)) {
Expression left = Expression.Property(pe, typeof(string).GetProperty("objects")); ;
Expression right = Expression.Constant(filtersObject.objects, typeof(string));
e4 = Expression.Equal(left, right);
}
var e1e2 = Expression.AndAlso(e1,e2);
var e1e2e3 = Expression.AndAlso(e1e2, e3);
var e1e2e3e4 = Expression.AndAlso(e1e2e3, e4);
var ExpressionTree = Expression.Lambda<Func<GlAccts, bool>>(e1e2e3e4, new[] { pe });
答案 0 :(得分:1)
您可以将子表达式与AndAlso
组合在一起。接下来的代码使用反射从Ledger
获取所有属性并创建动态lambda表达式:
public static Expression<Func<T, bool>> CreateExpression<T>(Ledger ledger)
{
var parameter = Expression.Parameter(typeof(T), "x");
Expression body = null;
foreach (var property in ledger.GetType().GetProperties())
{
var value = property.GetValue(ledger);
if (value == null)
continue;
var equals = Expression.Equal(
Expression.Property(parameter, property.Name),
Expression.Constant(value));
body = body == null ? equals : Expression.AndAlso(body, equals);
}
if (body == null) // no filters
body = Expression.Constant(true);
var lambda = Expression.Lambda<Func<T, bool>>(body, parameter);
return lambda;
}
如果Ledger中的所有属性都为null,则它将返回x => true
,该lambda将不会过滤任何内容