如何创建动态Linq查询以填充ASP.NET数据绑定ListView?

时间:2015-01-05 15:16:57

标签: asp.net vb.net linq listview

我在找出创建动态查询的正确方法时遇到了一些麻烦,我可以使用DropDownList控件中的值来过滤和排序/排序数据库查询的结果以填充ListView。我能够对单个查询进行硬编码,这样可以正常运行,除非需要花费大量精力并且不易更改。

我的代码如下(使用所有过滤器):

queryResult = From product In myEntities.InventoryProducts
              Where product.VendorID = ddlFilterVendor.SelectedValue And product.ItemType = ddlItemType.SelectedValue And product.LabelSize = ddlLabelSize.SelectedValue And product.PrintLabel = boolPrint And product.Edited = boolEdited
              Order By product.ID Ascending
              Select product

Return queryResult

有更好的方法吗?我希望能够从每个DropDownList中选择值并生成自定义WHERE子句以及ORDER BY子句。

非常感谢任何帮助,谢谢。

1 个答案:

答案 0 :(得分:0)

我可以举一个简单的例子来说明如何继续你的想法。我相信如果您通过StackOverflow查看或通过谷歌搜索,您将获得更好的动态表达式构建代码。相同的概念可用于按顺序排列。

void Main()
{
    var ops  = new List<Ops>
    { 
        new Ops
        {
            OperandType = typeof(string), 
            OpType=OpType.Equals, 
            OperandName = "Name", 
            ValueToCompare = "MM"  // in your case this will be the values from the dropdowns
        },
        new Ops
        {
            OperandType = typeof(int), 
            OpType=OpType.Equals, 
            OperandName = "ID", 
            ValueToCompare = 1
        },
    };
    var testClasses = new List<TestClass>
    {
        new TestClass { ID =1, Name = "MM", Date = new DateTime(2014,12,1)},
        new TestClass { ID =2, Name = "BB", Date = new DateTime(2014,12,2)}
    };

    // this will produce prop => ((prop.Name == "MM") And (prop.ID == 1))
    var whereDelegate = ExpressionBuilder.BuildExpressions<TestClass>(ops);

    foreach(var item in testClasses.Where(whereDelegate))
    {
        Console.WriteLine("ID " +item.ID);
        Console.WriteLine("Name " +item.Name);
        Console.WriteLine("Date" + item.Date);
    }
}

//在此定义其他方法和类

public enum OpType
{
    Equals
}

public class Ops
{
    public Type OperandType {get; set;}

    public OpType OpType {get; set;}

    public string OperandName {get;set;}

    public object ValueToCompare {get;set;}
}

public class TestClass
{   
    public int ID {get;set;}
    public string Name {get; set;}
    public DateTime Date {get;set;}
}

public class ExpressionBuilder
{
    public static Func<T,bool> BuildExpressions<T>( List<Ops> opList)
    {
        Expression currentExpression= null;
        var parameterExpression = Expression.Parameter(typeof(T), "prop");
        for(int i =0; i< opList.Count; i++)
        {
            var op =  opList[i];
            Expression innerExpression = null;
            switch(op.OpType)
            {
                case OpType.Equals :
                {
                    var propertyExpression = Expression.Property(parameterExpression , 
                                                                 op.OperandName);
                    var constExpression = Expression.Constant(op.ValueToCompare);
                    innerExpression = Expression.Equal(propertyExpression, 
                                                       constExpression);
                    break;
                }
            }

            if (i >0)
            {
                currentExpression = Expression.And(currentExpression, innerExpression);
            }
            else
            {
                currentExpression = innerExpression;
            }
        }
        var lambdaExpression = Expression.Lambda<Func<T,bool>>(currentExpression, 
                                                               new []{parameterExpression });
        Console.WriteLine(lambdaExpression);
        return lambdaExpression.Compile() ;
    }
}