我有一个3层的项目,所以所有的Linq-Querys都在DAL中。 现在我在Desig-Layer中实现了一个过滤功能,并希望在那里轻松过滤,但是如何?
Business.UserHandling uh = new Business.UserHandling();
List<DAL.Benutzer> users = uh.GetUserOverview();
gridUserOverview.AutoGenerateColumns = false;
gridUserOverview.DataSource = users;
gridUserOverview.DataBind();
我如何使用“users = users.Where(”bla = 1“)”?
之类的内容我试过了:
Business.UserHandling uh = new Business.UserHandling();
List<DAL.Benutzer> users = uh.GetUserOverview();
var filters = new Dictionary<string, object>();
filters.Add(Request.QueryString["value"], Request.QueryString["text"]);
users = users.Where(user => filters.All(filter => user.GetType().GetProperty(filter.Key).GetValue(user, null) == filter.Value)).ToList();
gridUserOverview.AutoGenerateColumns = false;
gridUserOverview.DataSource = users;
gridUserOverview.DataBind();
但它失败了...我过滤了“UserID = 1”,我有2个用户,过滤器应该是这些过滤器中的1个。但是返回的是0个用户。
答案 0 :(得分:2)
为了使用动态过滤器,您可以构建字典并通过反射验证过滤器:
var filters = new Dictionary<string, object>();
filters.Add("bla", 1);
users.Where(user => filters.All(filter => user.GetType().GetProperty(filter.Key).GetValue(user, null) == filter.Value));
修改支持所有可转换为字符串的类型:
var users = new List<User>();
users.Add(new User {Age = 1 });
users.Add(new User { Age = 2 });
var filters = new Dictionary<string, string>();
filters.Add("Age", "1");
var filtered = users.Where(user => filters.All(filter =>
{
var propertyInfo = user.GetType().GetProperty(filter.Key);
return Equals(propertyInfo.GetValue(user, null) , Convert.ChangeType(filter.Value, propertyInfo.PropertyType));
}));
Assert.AreEqual(1, filtered.Count());
答案 1 :(得分:1)
您可以更改GetUserOverview以接受表达式,这样您就可以进行自定义过滤。
实施例
public List<Benutzer> GetUserOverview(Func<Benutzer, bool> filter)
{
//get your users however you were getting them
var _result = new List<Benutzer>();
_result = _result.Where(filter);
return _result;
}
那会让你这样做:
List<DAL.Benutzer> users = uh.GetUserOverview(user => user.bla == 1);
<强>更新强>
如果您需要动态构建过滤器,可以这样做:
Expression<Func<Benutzer, bool> finalFilter;
if (doFirstFilter)
{
Expression<Func<Benutzer, bool> firstFilter = (user) => user.blah == 1;
}
if (doSecondFilter)
{
Expression<Func<Benutzer, bool> secondFitler =
(user) => user.other == "whatever";
finalFilter = Expression.Lambda<Func<Benutzer, bool>>(
Expression.And(firstFilter, secondFilter));
}
var users = uh.GetUserOverview(finalFilter.Compile());
你可以使用表达式做各种疯狂的事情。
答案 2 :(得分:0)
您是否尝试过从here
获取的有用代码public static IQueryable<T> AddEqualityCondition<T, V>(this IQueryable<T> queryable,string propertyName, V propertyValue)
{
ParameterExpression pe = Expression.Parameter(typeof(T), "p");
IQueryable<T> x = queryable.Where<T>(
Expression.Lambda<Func<T, bool>>(
Expression.Equal(Expression.Property(
pe,
typeof(T).GetProperty(propertyName)),
Expression.Constant(propertyValue, typeof(V)),
false,
typeof(T).GetMethod("op_Equality")),
new ParameterExpression[] { pe }));
return (x);
}