使用括号动态.NET EX pressions括号、动态、NET、EX

2023-09-06 05:44:12 作者:泪湿青衫

我在女巫用户可以填充在上一集的过滤器的网格。 用户必须填充在某些列:

 安道尔属性比较值
 

说,对于一个城市收集它可以过滤城市的

   - 名称StartsWith'一'
  和人口> 10000
  或人口与LT; 1000
 

我用的是动态 predicateBuilder ,这工作非常出色,直到括号的规定出现了。

正如你可以从查询见上文中所产生的集合,我们将有哪些城市 (Name.StartsWith'a'和人口> 10000)OR(人口与LT; 1000)。

ex文件不小心改成Internet文件如何改回去

为了打造前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