i有一个模型对象列表和一个包含根据该列表过滤的信息的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;
}
如何处理或情况。而且很容易 - 您只需根据每个<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)
。
任何想法如何有效地实现这一目标?在这种情况下,LINQ表现是表现吗?是否有更好的替代方案来获得更好的性能?
您可以按照以下方式进行:
-
使用一种方法创建一个接口Ifilter:
bool Evaluate(XElement element)
-
实现2类:
Filter
和CompositeFilter
。a。
返回结果的逻辑组成CompositeFilter
应具有儿童过滤器的列表,并指示其是否为和/或条件。Evaluate
方法实现应评估所有子过滤器,并根据和/或flagclass CompositeFilter { bool IsANDCondition; // if false, it is OR; List<IFilter> childFilters; bool Evaluate(XElement element) { bool result = IsANDCondition; foreach (var filter in childFilters) { bool b = filter.Evaluate(element); if (IsANDCondition) result = b && result; else result = b || result; } return result; } }
b。
Filter
应该具有所有可能的属性(iScasessentiment,Member,MemberType等),并在评估方法中实现逻辑
这样,您将拥有一个递归计算的谓词,您可以轻松地将其应用于记录:
CompositeFilter filter;
var fiteredRecords = records.Where(x=>filter.Evaluate(x));