Using brackets in dynamic .NET expressions

一个人想着一个人 提交于 2019-12-12 17:52:06

问题


I have a grid in witch a user can fill-in the "filter" on a collection. The user has to fill-in some columns:

AndOr  Property  Comparator  Value

say, for a Cities collection it could filter cities that

   -  Name       StartsWith  'a'
  AND Population     >       10000
  OR  Population     <       1000

I used the dynamic PredicateBuilder, that worked very well, until the "brackets" requirement appeared.

As you can see from the "query" above, in the resulting collection we will have cities which
(Name.StartsWith'a' AND Population > 10000) OR (Population < 1000).

In order to build the expression
Name.StartsWith'a' AND (Population > 10000 OR (Population < 1000) I need to use some brackets.

Now, the filter grid columns changed to

AndOr  LeftBracket  Property  Comparator  Value  RightBracket

Is there some "Group", "Open/CloseBracket" in the .NET Dynamic Expression library? An other way to realize it?

The code to "link" rows between them was the following

Private Function GetMyObjectsDataSource() As IQueryable(Of MyObject)
  ' start without any filter, get it all '
  Dim predicate = PredicateBuilder.True(Of MyObject)()
  Dim filterExpression As Expression(Of Func(Of MyObject, Boolean)) = predicate

  For Each row In grdFilter.Rows
    Dim rowExpression = GetExpressionFromRow(Of MyObject)(row)
    Dim compOp As LogicalOperator = row.Cells(ColumnKeys.AndOr).Value

    If compOp = LogicalOperator.Or Then
      filterExpression = [Or](filterExpression, rowExpression)
    Else
      filterExpression = [And](filterExpression, rowExpression)
    End If
  Next row

  Dim myObjects As List(Of MyObject) = Me._Container.GetMyObjects()
  Dim result As IQueryable(Of MyObject) =
    myObjects.AsQueryable().Where(filterExpression)

  Return result
End Function

回答1:


The best way to deal with this is to use nested sub-expressions in your expression tree. This likely involves changing the way you are interpreting the user's input. Basically whenever you encounter a LeftBracket element, you would recursively build a sub-expression up to the next RightBracket element in the current scope. Then you would assign that entire sub-expression as a node in the current operation.

From reviewing the code sample in your question, I would suspect the best place to do this is in the "GetExpressionFromRow" function. Unfortunately, I don't think the "GetExpressionFromRow" is part of the code library you referenced in your question.

If you can update your question to include the GetExpressionFromRow and dependencies, I can try to examine further and give a more specific answer.

The basic algorithm behind this technique is called a recursive descent parser. See some general information here: http://en.wikipedia.org/wiki/Recursive_descent_parser



来源:https://stackoverflow.com/questions/7306101/using-brackets-in-dynamic-net-expressions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!