C# 根据xml中的信息筛选列表
我有一个模型对象列表和一个包含信息的xml,根据这些信息应该对列表进行过滤。我需要一个filter方法,它接受列表和xml并返回过滤后的列表。我需要它是通用的,这样它可以处理一个列表,即ProductModel或CustomerModel列表。xml可以有C# 根据xml中的信息筛选列表,c#,.net,xml,linq,filtering,C#,.net,Xml,Linq,Filtering,我有一个模型对象列表和一个包含信息的xml,根据这些信息应该对列表进行过滤。我需要一个filter方法,它接受列表和xml并返回过滤后的列表。我需要它是通用的,这样它可以处理一个列表,即ProductModel或CustomerModel列表。xml可以有元素或元素,如下所示。FilterCompositionLogicalOperator属性指示它是逻辑的和操作还是逻辑的或操作FilterOperator表示eksampleIsEqualTo=0IsLessThan=1等的枚举 <?xm
元素或
元素,如下所示。FilterCompositionLogicalOperator
属性指示它是逻辑的和操作还是逻辑的或操作FilterOperator
表示eksampleIsEqualTo=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>
我的模型对象有一个方法GetColumnValue(columnName)
,该方法接受columnName并返回其值
你知道如何有效地做到这一点吗?LINQ在这种情况下有表现吗?为了获得更好的性能,是否有更好的替代方案?您可以采用以下方法:
使用方法创建接口IFilter:bool Evaluate(XElement元素)
实现两个类:Filter
和CompositeFilter
aCompositeFilter
应该有一个子过滤器列表和一个标志,指示它是否为and或or条件<代码>评估
方法实现应评估所有子过滤器,并根据和/或标志返回结果的逻辑组成
class 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;
}
}
如果我是你,我会使用你的Xml来构建一个你在Where子句中使用的表达式。这可能很有用。IAdvancedFilterable
的定义是什么?IAdvancedFilterable
只是我的模型对象实现的一个接口。这样我就可以一般地处理它们了。它公开了一个属性Source
,该属性允许访问实际模型的属性和公共方法。我已经编辑了您的标题。请参阅“”,其中的共识是“不,他们不应该”。
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;
class 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;
}
}
CompositeFilter filter;
var fiteredRecords = records.Where(x=>filter.Evaluate(x));