簡體   English   中英

用戶定義的過濾器/查詢?

[英]User defined filters/queries?

我正在嘗試找出一種方法,允許我的應用程序的用戶定義自己的查詢或可以應用於集合的過濾器。 我想最終提供一個直觀的用戶界面來創建這些過濾器(請參見下圖),但是最初,如果用戶必須鍵入文本查詢字符串,那將是可以的。 我還需要能夠將這些用戶定義的查詢序列化為字符串,以便將其與項目的其余信息一起保存。

UI 替代文字 示例 http://dl.dropbox.com/u/113068/filterUI.jpg

我正在尋找您可以從類似SQL查詢之類的功能中獲取的功能,例如數值條件(小於,大於),字符串條件(包含,以,以結尾)或布爾條件(對或錯) )。 我還希望能夠使用布爾邏輯(例如OR,AND和NOT)對條件進行分組。

我開始使用諸如NodeFilter,AbsNodeCondition,NodeStringCondition,NodeConditionOrJoin等之類的類從頭開始做這件事。但是我感覺我正在重新發明輪子,特別是當有類似Linq的東西可用時,我沒有沒有機會花費很多時間。

我可以以某種方式允許用戶在文本框中輸入對對象的Linq查詢,然后以編程方式將字符串轉換為可以應用於我的集合的真實Linq查詢嗎? 還是我可以允許用戶創建和保存查詢的其他方式? 我還需要一種將過濾器/查詢序列化為字符串的方法,以便將其與程序的其余信息一起保存。

這不一定是理想的解決方案,但是MetaLinq項目為LINQ表達式類提供了可序列化的包裝器。

這是一個在雙向序列化表達式后如何重新創建和執行表達式的示例。

首先,我們將現有的lamba表達式序列化為xml文檔。

var originalExpr = EditableExpression.CreateEditableExpression<string, bool>(
    str => str.Length > 3);
var serializer = new XmlSerializer(originalExpr.GetType());
string xml;

using (var writer = new StringWriter())
{
    serializer.Serialize(writer, originalExpr);
    xml = writer.ToString();
}

然后,我們將其反序列化,解包裝並將其編譯回委托中,以准備執行。

EditableExpression newExpr;

using (var reader = new StringReader(xml))
{
    newExpr = (EditableExpression) serializer.Deserialize(reader);
}

var expr = (Expression<Func<string, bool>>) newExpr.ToExpression();
var items = new[] {"one", "two", "three"};
var result = items.Count(expr.Compile());
Debug.Assert(result == 1);

這就是序列化表達式的樣子。

<EditableLambdaExpression xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <NodeType>Lambda</NodeType>
  <TypeName>System.Func`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</TypeName>
  <Body xsi:type="EditableBinaryExpression">
    <NodeType>GreaterThan</NodeType>
    <TypeName>System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</TypeName>
    <Left xsi:type="EditableMemberExpression">
      <NodeType>MemberAccess</NodeType>
      <Expression xsi:type="EditableParameterExpression">
        <NodeType>Parameter</NodeType>
        <TypeName>System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</TypeName>
        <Name>str</Name>
      </Expression>
      <MemberName>System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
Int32 Length</MemberName>
    </Left>
    <Right xsi:type="EditableConstantExpression">
      <NodeType>Constant</NodeType>
      <Value xsi:type="xsd:int">3</Value>
    </Right>
  </Body>
  <Parameters>
    <EditableExpression xsi:type="EditableParameterExpression">
      <NodeType>Parameter</NodeType>
      <TypeName>System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</TypeName>
      <Name>str</Name>
    </EditableExpression>
  </Parameters>
</EditableLambdaExpression>

不幸的是,System.Linq.Expressions無法序列化,甚至在4.0中也是如此。 如果必須跨越應用程序域邊界,則必須訴諸於編寫自己的表達式樹和訪問者以從中生成查詢。 否則,在框中表達樹會很好。

除此之外,您可能會找到一些適合您需求的動態linq。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM