在ASP.NET MVC3中,根据下拉列表数据获取列表。

6
我在我的模块中有两个下拉列表。
在一个下拉列表中,我硬编码了所有的操作符,例如 <,>,<=,>=,==
在第二个下拉列表中,我硬编码了员工薪水,例如1000,2000,3000,4000....50000
现在,如果我从第一个列表中选择<,从第二个列表中选择2000并单击提交按钮,我应该会得到薪水小于2000的员工列表。
我想在asp.net mvc3中完成这个任务,我该怎么做?我需要为此写存储过程吗?
我已经创建了下拉列表:
viewModel.OperatorsList = new[]
{
  new SelectListItem { Value = "<", Text = "<" },
  new SelectListItem { Value = ">", Text = ">" },  
  new SelectListItem { Value = "<=", Text = "<=" },
  new SelectListItem { Value = ">=", Text = ">=" },
  new SelectListItem { Value = "==", Text = "==" }
};

viewModel.SalaryList = new[]
{
  new SelectListItem { Value = "1000", Text = "1000" },
  new SelectListItem { Value = "2000", Text = "2000" },  
  new SelectListItem { Value = "3000", Text = "3000" },

  // and so on
};

我曾使用以下代码在视图中显示下拉列表:

<%: Html.DropDownListFor(x => x.Operators, Model.OperatorsList)%>

请展示您生成的两个下拉列表的HTML代码。 - Raphaël Althaus
1
顺便问一句,你在用 EF 吧? - Raphaël Althaus
这个满足你的问题吗?是的,我正在使用实体框架。 - Keren Caelen
1个回答

6

好的,你可以像这样做

假设viewModel是你的viewModel,并且你有一个实体Employee,它有一个属性Salary(在这个示例中是int,在实际世界中可能是decimal

创建一个静态的帮助类

public static class MyHelper
    {
        // a dictionary for your operators and corresponding ExpressionType
        public static Dictionary<string, ExpressionType> ExpressionTypeDictionary = new Dictionary<string, ExpressionType>
        {
            {"<", ExpressionType.LessThan},
            {">", ExpressionType.GreaterThan},
            {">=", ExpressionType.GreaterThanOrEqual}
            //etc
        };
        //a method to filter your queryable
        public static IQueryable<Employee> FilterSalary(this IQueryable<Employee> queryable, int salary, string operatorType)
        {
            //left part of the expression : m
            var parameter = Expression.Parameter(typeof(Employee), "m");
            //body is the right part of the expression : m
            Expression body = parameter;
            //m.Salary
            body = Expression.Property(body, "Salary");
            //m.Salary <= 1000 (for example)
            body = Expression.MakeBinary(ExpressionTypeDictionary[operatorType], body, Expression.Constant(salary));
            //m => m.Salary <=1000
            var lambda = Expression.Lambda<Func<Employee, bool>>(body, new[] { parameter });
            //so it will be queryable.Where(m => m.Salary <= 1000)
            return queryable.Where(lambda);
        }
}

用法

var queryable = context.All<Employee>();//or something like that, returning an IQueryable<Employee>
queryable = queryable.FilterSalary(viewModel.Salary, viewModel.Operators);

@K2_Ketu 嗯,扩展方法 Where 接受一个 Expression<Func<T, bool>> 作为参数。该方法只是构建此表达式,将其转换为 lambda,并将其传递给 Where 方法。您可以尝试逐步调试并查看 body 中的内容,或者搜索表达式树。我也会在我的代码中添加一些注释。 - Raphaël Althaus
@K2_Ketu 看得好,这是一个笔误,我一开始制作了一个更通用的版本,忘记纠正了。已编辑。 - Raphaël Althaus
Althaus:非常感谢,这是一个完美的答案 :-) - Keren Caelen
@Raphaël Althaus,你能否添加“包含”函数或任何用户定义的字符串操作函数?我认为这可能会很有用。 - Lei Yang
1
@LeiYang 嗯,Contains和其他方法(不是“比较运算符”)需要一些其他的逻辑(你需要使用反射来获取方法,并使用Expression.Call)。你可以在这里看看:https://dev59.com/wW3Xa4cB1Zd3GeqPjuBj - Raphaël Althaus
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接