简单的linq问题:如何过滤源?

时间:2009-11-02 15:05:41

标签: linq

我有一个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个用户。

3 个答案:

答案 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);
        }