Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Silverlight 如何从表达式树动态构造谓词方法?_Silverlight_Filter_Expression Trees_Predicatebuilder - Fatal编程技术网

Silverlight 如何从表达式树动态构造谓词方法?

Silverlight 如何从表达式树动态构造谓词方法?,silverlight,filter,expression-trees,predicatebuilder,Silverlight,Filter,Expression Trees,Predicatebuilder,以下是场景: Silverlight 4.0、DataGrid、PagedCollectionView项目资源。 目的是将过滤器应用于PCV。过滤器需要是一个谓词(方法)——其中方法对对象实现一些逻辑,并返回true/false以供包含。 我需要在过滤器逻辑中选择性地包含3个不同的标准,显式代码很快就会变得难看。我们不想那样,是吗 因此,我发现有一种方法可以使用PredicateBuilder构建表达式树,并将其传递到Linq。其中,la: IQueryable<Product> S

以下是场景: Silverlight 4.0、DataGrid、PagedCollectionView项目资源。 目的是将过滤器应用于PCV。过滤器需要是一个
谓词(方法)
——其中方法对对象实现一些逻辑,并返回true/false以供包含。 我需要在过滤器逻辑中选择性地包含3个不同的标准,显式代码很快就会变得难看。我们不想那样,是吗

因此,我发现有一种方法可以使用PredicateBuilder构建表达式树,并将其传递到Linq。其中,la:

IQueryable<Product> SearchProducts (params string[] keywords)
{
  var predicate = PredicateBuilder.False<Product>();

  foreach (string keyword in keywords)
  {
    string temp = keyword;
    predicate = predicate.Or (p => p.Description.Contains (temp));
  }
  return dataContext.Products.Where (predicate);
}
IQueryable SearchProducts(参数字符串[]关键字)
{
var predicate=PredicateBuilder.False();
foreach(关键字中的字符串关键字)
{
字符串temp=关键字;
谓词=谓词。或(p=>p.Description.Contains(temp));
}
返回dataContext.Products.Where(谓词);
}
[顺便说一句,这不是我想做的]

有了3个可选条件,我想写下如下内容:

 Ratings.Filter = BuildFilterPredicate();  // Ratings = the PagedCollectionView


private Predicate<object> BuildFilterPredicate()
{
  bool FilterOnOrder = !String.IsNullOrEmpty(sOrderNumberFilter);
  var predicate = PredicateBuilder.False<object>();
  if (ViewMineOnly)
  {
    predicate = predicate.And(Rating r => sUserNameFilter == r.Assigned_To);
  }
  if (ViewStarOnly)
  {
    predicate = predicate.And(Rating r => r.Star.HasValue && r.Star.Value > 0);
  }
  if (FilterOnOrder)
  {
    predicate = predicate.And(Rating r => r.ShipmentInvoice.StartsWith(sOrderNumberFilter));
  }
  return predicate;
}
Ratings.Filter=BuildFilterPredicate();//评级=页面集合视图
私有谓词BuildFilterPredicate()
{
bool filterOrder=!String.IsNullOrEmpty(sOrderNumberFilter);
var predicate=PredicateBuilder.False();
如果(仅限查看)
{
谓词=谓词和(评级r=>sUserNameFilter==r.Assigned_To);
}
如果(仅限ViewStar)
{
谓词=谓词和(评级r=>r.Star.HasValue&&r.Star.Value>0);
}
if(过滤器订单)
{
谓词=谓词和(评级r=>r.ShipmentInvoice.StartsWith(sOrderNumberFilter));
}
返回谓词;
}
当然,这不会编译,因为PredicateBuilder创建的是一个
表达式
,而不是实际的谓词方法。但是我看到有很多方法可以将表达式树转换成方法,所以在我看来,应该有一种方法可以实现我想要的,而不必求助于一堆嵌套的if/then/else语句

所以问题是-有没有一种方法可以动态地构建谓词方法


TIA

我也面临同样的问题。我有3个标准。 我所做的是:

  • 一种验证每个标准的方法
  • 一种验证对象的方法
代码看起来非常干净,易于维护

Ratings.Filter = new predicate<objects>(validateObject);

private bool validateObject(object o)
{
  return validateFirstCriteria(o) && 
         validateSecondCriteria(o) && 
         validateThirdCriteria(o);
}

private bool validateFirstObject(object o)
{
  if (ViewMineOnly)
  {
    Rating r = o as Rating;
    if (o != null)
    {
      return  (r.Star.HasValue && r.Star.Value > 0);
    }
  }
  return false;
}
private bool validateSecondObject(object o)
{
  if (ViewStarOnly)
  {
    Rating r = o as Rating;
    if (o != null)
    {
      return sUserNameFilter == r.Assigned_To;
    }
  }
  return false;
}
private bool validateThirdObject(object o)
{
  if (FilterOnOrder)
  {
    Rating r = o as Rating;
    if (o != null)
    {
      return r.ShipmentInvoice.StartsWith(sOrderNumberFilter);
    }
  }
  return false;
}
Ratings.Filter=新谓词(validateObject);
私有布尔验证对象(对象o)
{
返回validateFirstCriteria(o)和
验证第二个标准(o)和
验证标准(o);
}
私有bool validateFirstObject(对象o)
{
如果(仅限查看)
{
额定值r=o为额定值;
如果(o!=null)
{
返回(r.Star.HasValue&&r.Star.Value>0);
}
}
返回false;
}
私有布尔validateSecondObject(对象o)
{
如果(仅限ViewStar)
{
额定值r=o为额定值;
如果(o!=null)
{
返回sUserNameFilter==r.Assigned\u To;
}
}
返回false;
}
私有布尔ValidateHirdObject(对象o)
{
if(过滤器订单)
{
额定值r=o为额定值;
如果(o!=null)
{
返回r.ShipmentInvoice.StartWith(sOrderNumberFilter);
}
}
返回false;
}
编辑

如果您想坚持使用表达式树。你可以看看这里:

可以将表达式树转换为lambda表达式,然后编译lambda表达式。之后,您可以将其用作一种方法。例如:

        // The expression tree to execute.
        BinaryExpression be = Expression.Power(Expression.Constant(2D), Expression.Constant(3D));

        // Create a lambda expression.
        Expression<Func<double>> le = Expression.Lambda<Func<double>>(be);

        // Compile the lambda expression.
        Func<double> compiledExpression = le.Compile();

        // Execute the lambda expression.
        double result = compiledExpression();

        // Display the result.
        Console.WriteLine(result);

        // This code produces the following output:
        // 8
//要执行的表达式树。
BinaryExpression be=Expression.Power(Expression.Constant(2D)、Expression.Constant(3D));
//创建一个lambda表达式。
表达式le=表达式λ(be);
//编译lambda表达式。
Func compiledExpression=le.Compile();
//执行lambda表达式。
双重结果=compiledExpression();
//显示结果。
控制台写入线(结果);
//此代码生成以下输出:
// 8

我也面临同样的问题。我有3个标准。 我所做的是:

  • 一种验证每个标准的方法
  • 一种验证对象的方法
代码看起来非常干净,易于维护

Ratings.Filter = new predicate<objects>(validateObject);

private bool validateObject(object o)
{
  return validateFirstCriteria(o) && 
         validateSecondCriteria(o) && 
         validateThirdCriteria(o);
}

private bool validateFirstObject(object o)
{
  if (ViewMineOnly)
  {
    Rating r = o as Rating;
    if (o != null)
    {
      return  (r.Star.HasValue && r.Star.Value > 0);
    }
  }
  return false;
}
private bool validateSecondObject(object o)
{
  if (ViewStarOnly)
  {
    Rating r = o as Rating;
    if (o != null)
    {
      return sUserNameFilter == r.Assigned_To;
    }
  }
  return false;
}
private bool validateThirdObject(object o)
{
  if (FilterOnOrder)
  {
    Rating r = o as Rating;
    if (o != null)
    {
      return r.ShipmentInvoice.StartsWith(sOrderNumberFilter);
    }
  }
  return false;
}
Ratings.Filter=新谓词(validateObject);
私有布尔验证对象(对象o)
{
返回validateFirstCriteria(o)和
验证第二个标准(o)和
验证标准(o);
}
私有bool validateFirstObject(对象o)
{
如果(仅限查看)
{
额定值r=o为额定值;
如果(o!=null)
{
返回(r.Star.HasValue&&r.Star.Value>0);
}
}
返回false;
}
私有布尔validateSecondObject(对象o)
{
如果(仅限ViewStar)
{
额定值r=o为额定值;
如果(o!=null)
{
返回sUserNameFilter==r.Assigned\u To;
}
}
返回false;
}
私有布尔ValidateHirdObject(对象o)
{
if(过滤器订单)
{
额定值r=o为额定值;
如果(o!=null)
{
返回r.ShipmentInvoice.StartWith(sOrderNumberFilter);
}
}
返回false;
}
编辑

如果您想坚持使用表达式树。你可以看看这里:

可以将表达式树转换为lambda表达式,然后编译lambda表达式。之后,您可以将其用作一种方法。例如:

        // The expression tree to execute.
        BinaryExpression be = Expression.Power(Expression.Constant(2D), Expression.Constant(3D));

        // Create a lambda expression.
        Expression<Func<double>> le = Expression.Lambda<Func<double>>(be);

        // Compile the lambda expression.
        Func<double> compiledExpression = le.Compile();

        // Execute the lambda expression.
        double result = compiledExpression();

        // Display the result.
        Console.WriteLine(result);

        // This code produces the following output:
        // 8
//要执行的表达式树。
BinaryExpression be=Expression.Power(Expression.Constant(2D)、Expression.Constant(3D));
//创建一个lambda表达式。
表达式le=表达式λ(be);
//编译lambda表达式。
Func compiledExpression=le.Compile();
//执行lambda表达式。
双重结果=compiledExpression();
//显示结果。
控制台写入线(结果);
//此代码生成以下输出:
// 8

感谢本杰明的提示和这篇帖子-> 我想出来了。
其实质是:


私有静态Predica
private Predicate<object> ConvertExpressionToPredicate(Expression<Func<object, bool>> exp)
{
  Func<object, bool> func = exp.Compile();
  Predicate<object> predicate = new Predicate<object>(func);
  //Predicate<object> predicate = t => func(t);     // also works
  //Predicate<object> predicate = func.Invoke;      // also works
  return predicate;
}
private Expression<Func<object, bool>> BuildFilterExpression()
{
  ...snip...
  var predicate = PredicateBuilder.True<object>();
  if (ViewMineOnly)
  {
    predicate = predicate.And(r => ((Rating)r).Assigned_To.Trim().ToUpper() == sUserNameFilter || ((Rating)r).Assigned_To.Trim().ToUpper() == "UNCLAIMED");
  }
  if (ViewStarOnly)
  {
    predicate = predicate.And(r => ((Rating)r).Star.HasValue && ((Rating)r).Star.Value > 0);
  }
  if (FilterOnOrder)
  {
    predicate = predicate.And(r => ((Rating)r).ShipmentInvoice.Trim().ToUpper().StartsWith(sOrderNumberFilter));
  }
  if (ViewDueOnly)
  {
    predicate = predicate.And(r => ((Rating)r).SettlementDueDate <= ThisThursday);
  }
  return predicate;
}
Ratings.Filter = ConvertExpressionToPredicate(BuildFilterExpression());