如何在where子句中创建动态linq xml?

时间:2017-01-09 07:27:24

标签: linq-to-xml

我有一个xml文件:

<student>
     <st id="01" name="lan" age="20" sex="male"/>
     <st id="02" name="chau" age="21" sex="female"/>
     <st id="03" name="tuan" age="22 sex="female"/>
     <st id="04" name="minh" age="23" sex="female"/>
</student>

我创建了一个linq xml,如下所示:

XDocument xdoc=XDocument.Load("path to xml file above");
var element = from ele in xdoc.Element("student").Elements("st")
              where ele != null && ele.Attribute("id").Value == "02" 
              && ele.Attribute("name").Value == "chau" 
              && ele.Attribute("age").Value == "21"
              && ele.Attribute("sex").Value == "female"
   select ele; 

此查询运行正常。但现在我想构建动态&#34; where子句&#34;数组字符串中的属性名称[] att = new string [4] {&#34; id&#34;,&#34; name&#34;,&#34; age&#34;,&#34; sex&#34 ;}; string [] value = new string [4] {&#34; 02&#34;,&#34; chau&#34;,&#34; 21&#34;,&#34; female&#34;} 如何编写where子句,如:

...    
where ele != null && ele.Attribute(att[i]).Value == value[i] ? 
...

非常感谢你。

1 个答案:

答案 0 :(得分:0)

构建一个包含属性名称及其值

的类过滤器
public  class  Filter
{
    public  string  Property { get ; set ; }
    public  object  Value { get ; set ; }
}

代表

public  Func <Student , bool> Build(IList <Filter > filters)

然后创建StudentExpressionBuilder类

public  class  StudentExpressionBuilder
{
    public static Func<Student, bool> Build(IList<Filter2> filters)
    {
        ParameterExpression param = Expression.Parameter(typeof(Student), "t" );
        Expression  exp = null ;

        if  (filters.Count == 1)
            exp = GetExpression(param, filters[0]);
        else  if  (filters.Count == 2)
            exp = GetExpression(param, filters[0], filters[1]);
        else
        {
            while  (filters.Count > 0)
            {
                var  f1 = filters[0];
                var  f2 = filters[1];

                if  (exp == null )
                    exp = GetExpression(param, filters[0], filters[1]);
                else
                    exp = Expression.AndAlso(exp, GetExpression(param, filters[0], filters[1]));

                filters.Remove(f1);
                filters.Remove(f2);

                if (filters.Count == 1)
                {
                    exp = Expression.AndAlso(exp, GetExpression(param, filters[0]));
                    filters.RemoveAt(0);
                }
            }
        }

        return Expression.Lambda<Func<Student, bool>>(exp, param).Compile();
    }

    private static Expression GetExpression(ParameterExpression param, Filter2 filter)
    {
        MemberExpression member = Expression.Property(param, filter.PropertyName);
        ConstantExpression constant = Expression.Constant(filter.Value);
        return Expression.Equal(member, constant);
    }

    private static BinaryExpression GetExpression
    (ParameterExpression param, Filter2 filter1, Filter2 filter2)
    {
        Expression bin1 = GetExpression(param, filter1);
        Expression bin2 = GetExpression(param, filter2);

        return  Expression.AndAlso(bin1, bin2);
    }
}

创建过滤器列表

List<Filter> filter = new  List<Filter>
{
    new  Filter  { PropertyName = "name" , Value = "chau"  },
    new  Filter  { PropertyName = "age" , Value = "21"  }
};

并最终查询您的数据

var  deleg = StudentExpressionBuilder.Build(filter);
var  filteredCollection = students.Where(deleg).ToList();