我有以下代码可以正确返回六个对象的列表
var items = db.items.take(100);
var result = items.Where(m => m.Cost.ToString().ToLower().Contains("67.5")).ToList(); //returns 6 items
我正在尝试使用动态表达式来做同样的事情。
// Print out the expression.
// .ToString() returns "m => m.Cost.ToString().ToLower().Contains("67.5")"
var whereClause = ContainsPredicate<item>("Cost", "67.5");
var result = items.Where(whereClause).ToList(); //returns 0 items
[当我尝试使用sql profiler来查看发送到数据库的内容时,我注意到它删除了我的子句并添加了WHERE 0 = 1
ContainsPredicate方法实现:
public static Expression<Func<T, bool>> ContainsPredicate<T>(string memberName, string searchValue)
{
var parameter = Expression.Parameter(typeof(T), "m");
var member = Expression.PropertyOrField(parameter, memberName);
MethodCallExpression memberToString = Expression.Call(Expression.Constant(member), member.GetType().GetMethod("ToString", Type.EmptyTypes));
MethodCallExpression memberToLower = Expression.Call(memberToString,"ToLower", null);
var body = Expression.Call(memberToLower,"Contains",Type.EmptyTypes,Expression.Constant(searchValue));
return Expression.Lambda<Func<T, bool>>(body, parameter);
}
任何建议都值得赞赏。谢谢。
public static void Test()
{
var myItem = new Item() { Cost = 67.5 };
var items = new List<Item> { myItem };
var result = items.Where(m =>
m.Cost.ToString().ToLower().
Contains("67,5")).ToList();
var whereClause = ContainsPredicate<Item>("Cost", "67,5");
// var test1 = whereClause(myItem);
var result2 = items.Where(whereClause).ToList(); // returns 1 result in my case
}
public static Func<T, bool> ContainsPredicate<T>(string memberName, string searchValue)
{
var parameter = Expression.Parameter(typeof(T), "m");
var member = Expression.PropertyOrField(parameter, memberName);
// Mistake was here:
var doubleToStr = member.Type.GetMethod("ToString", Type.EmptyTypes);
MethodCallExpression memberToString = Expression.Call(member, doubleToStr);
MethodCallExpression memberToLower =
Expression.Call(memberToString, "ToLower", null);
var body = Expression.Call(memberToLower, "Contains", Type.EmptyTypes
, Expression.Constant(searchValue));
var lamb = Expression.Lambda<Func<T, bool>>(body, parameter);
// we need to compile
return lamb.Compile();
}
我做的第一件事只是编译memberToLower
,它返回字符串“ m.cost”而不是您的double。 “ m.cost”显然不会包含“ 67.5”。所以你去了。
确定要不要这样的东西:
public static Func<T, bool> ContainsPredicate2<T>(string memberName, string searchValue)
{
var prop = typeof(T).GetProperty(memberName);
Func<T, bool> func = (T obj2) =>
prop.GetValue(obj2).ToString().ToLower().Contains(searchValue);
return func;
}