【发布时间】:2012-10-13 08:06:12
【问题描述】:
我有一个模型对象列表和一个包含信息的 xml,根据这些信息应该过滤列表。我需要一个过滤器方法,它接受列表和 xml 并返回过滤后的列表。我需要它是通用的,以便它可以处理一个列表,即 ProductModel 或一个 CustomerModel 列表。 xml 可以有<descriptor> 元素或<composite> 元素,如下所示。 FilterCompositionLogicalOperator 属性指示它是逻辑AND 还是逻辑OR 操作。 FilterOperator 代表 eksample 的枚举 IsEqualTo = 0 IsLessThan=1 等。
<?xml version="1.0" encoding="utf-8" ?>
<advanced FilterCompositionLogicalOperator="1">
<descriptor IsCaseSensitive="false" Member="SalesPrice" MemberType="System.Decimal" FilterOperator="5">800</descriptor>
<descriptor IsCaseSensitive="false" Member="CostPrice" MemberType="System.Decimal" FilterOperator="5">300</descriptor>
<composite FilterCompositionLogicalOperator="0">
<descriptor IsCaseSensitive="false" Member="CostPrice" MemberType="System.Decimal" FilterOperator="5">150</descriptor>
<descriptor IsCaseSensitive="false" Member="ProductId" MemberType="System.String" FilterOperator="0">400</descriptor>
</composite>
</advanced>
我尝试过这样的事情:
public List<IAdvancedFilterable> HandleXML(XElement xml, IEnumerable<IAdvancedFilterable> filterableList)
{
foreach (XElement element in xml.Elements())
{
// if composite, I call the method recursively giving it the composite element and list
// else I read all the attributes of the <descriptor> element. decide the type of the elementValue
// and then I call helper method 'Filter'
filtered = Filter(compareOpr, colNameAtt.Value, elementValue, list);
// Which filters the list according to this <descriptor> element using LINQ.
}
return filtered;
}
如何处理 OR 情况。 AND 很简单 - 您只需根据每个 <descriptor> 进行过滤,无需任何进一步考虑就可以了。
过滤器辅助方法打开FilterOperator,例如:
case FilterOperator.IsLessThan:
if (elementValue.IsInt())
return list.Where(d => Convert.ToInt32(d.Source.GetColumnValue(columnName)) < Convert.ToInt32(elementValue));
if (elementValue.IsDecimal())
return list.Where(d => Convert.ToDecimal(d.Source.GetColumnValue(columnName)) < Convert.ToDecimal(elementValue));
break;
我的模型对象有一个方法 GetColumnValue(columnName),它接受一个 columnName 并返回它的值。
知道如何有效地实现这一目标吗?在这种情况下 LINQ 是高性能的吗?是否有更好的替代方案以获得更好的性能?
【问题讨论】:
-
如果我是你,我会使用你的 Xml 来构建你在 Where 子句中使用的表达式。这可能有用albahari.com/nutshell/predicatebuilder.aspx
-
IAdvancedFilterable的定义是什么? -
IAdvancedFilterable只是我的模型对象实现的接口。这样我就可以通用地处理它们。它公开了一个属性Source,可以访问实际模型的属性和公共方法。 -
我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。
标签: c# .net xml linq filtering