我在女巫用户可以填充在上一集的过滤器的网格。 用户必须填充在某些列:
安道尔属性比较值
说,对于一个城市收集它可以过滤城市的
- 名称StartsWith'一'
和人口> 10000
或人口与LT; 1000
我用的是动态 predicateBuilder ,这工作非常出色,直到括号的规定出现了。
正如你可以从查询见上文中所产生的集合,我们将有哪些城市
(Name.StartsWith'a'和人口> 10000)OR(人口与LT; 1000)。
为了打造前pression
Name.StartsWith'a'AND(人口与GT; 10000(人口与LT 1000)
我需要使用一些括号。
现在,过滤器网格列改为
安道尔LEFTBRACKET属性比较值RIGHTBRACKET
有一些集团,在.NET动态防爆pression库打开/ CloseBracket? 一个其他的方式去实现它?
在code连接他们之间的行是以下
专用功能GetMyObjectsDataSource()作为IQueryable的(作者为MyObject)
开始没有任何过滤,得到这一切
昏暗predicate = predicateBuilder.True(作者为MyObject)()
昏暗filterEx pression为Ex pression(中Func键(中为MyObject,布尔))= predicate
对于每行中grdFilter.Rows
昏暗rowEx pression = GETEX pressionFromRow(作者为MyObject)(行)
昏暗compOp作为LogicalOperator = row.Cells(ColumnKeys.AndOr).value的
如果compOp = LogicalOperator.Or然后
filterEx pression = [OR](filterEx pression,rowEx pression)
其他
filterEx pression = [和](filterEx pression,rowEx pression)
结束如果
下一行
昏暗myObjects方式列表(作者为MyObject)= Me._Container.GetMyObjects()
昏暗的结果作为IQueryable的(作者为MyObject)=
myObjects.AsQueryable()。在哪里(filterEx pression)
返回结果
端功能
解决方案
来处理,这是使用嵌套子EX pressions在你的前pression树的最佳方式。这可能涉及到改变你的方式是相互$ P $ pting用户的输入。基本上,当你遇到一个LEFTBRACKET元素,你会递归构建子前pression达在当前范围内的下一个RIGHTBRACKET元素。然后,你会分配一个整个子-EX pression作为当前操作的一个节点。
从审查code样品在你的问题,我会怀疑这样做是在GETEX pressionFromRow功能的最佳场所。不幸的是,我不认为GETEX pressionFromRow是你在你的问题中引用的code库的一部分。
如果您可以更新您的问题,包括对GETEX pressionFromRow和依赖性,我可以尝试进一步审查,并提供一个更明确的答案。
这种技术背后的基本算法称为递归下降解析器。看到这里的一些基本信息: http://en.wikipedia.org/wiki/Recursive_descent_parser
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
解决方案
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