首先我们的Entity 或者说数据库的结构如下
另外如下面代码,我们有一个用于传递name=value对,及查询谓词的model
1: public ActionResult Index(QueryModel model)
2: {
3: using(var db=new DbEntities())
4: {
5: var list = db.Users.Where(model).ToList();
6: return View(list);
7: }
8: }
我命名之为QueryModel。它由Action的参数传入,再传入EF的Where扩展方法,它是构建Lambda表达式的原型,上面是我们的一个通用的查询Action的代码。
而QueryModel的代码为
QueryModel的唯一一个属性Items,是一个ConditionItem的集合,它里面存着所有的查询条件。
而ConditionItem里面的属性
而我们在页面上类似
1: <form action="" method="post">
2: 姓名:<input id="Name" name="[Like]Name" type="text" value="" />
3: Email:<input id="Email" name="[Equal]Email" type="text" value="" /><br />
4: Id: <input id="Id" name="[Equal]Id" type="text" value="" />
5: 生日: <input id="Birthday" name="[Equal]Birthday" type="text" value="" /><br />
6: <input type="submit" value="查询" />
7: </form>
这样的表单,我们提交到服务器端,我们要进行ASP.NET MVC 中IModelBinder的转换,要将querystring 或 postdata中的KeyValuePair转换为我们的ConditionItem。
当然,我们除了谓词Method之外,还有Prefix以及OrGroup要从客户端提交过来所以我们就要制定一个规则
我们约定
我们可以通过以下IModelBinder的实现将Request.QueryString或Request.Form中的值转换到QueryModel中:
1: public class SearchModelBinder : IModelBinder
2: {
3: public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
4: {
5: var model = (QueryModel)(bindingContext.Model ?? new QueryModel());
6: var dict = controllerContext.HttpContext.Request.Params;
7: var keys = dict.AllKeys.Where(c => c.StartsWith("["));//我们认为只有[开头的为需要处理的
8: if (keys.Count() != 0)
9: {
10: foreach (var key in keys)
11: {
12: if (!key.StartsWith("[")) continue;
13: var val = dict[key];
14: //处理无值的情况
15: if (string.IsNullOrEmpty(val)) continue;
16: AddSearchItem(model, key, val);
17: }
18: }
19: return model;
20: }
21:
22: /// <summary>
23: /// 将一组key=value添加入QueryModel.Items
24: /// </summary>
25: /// <param name="model">QueryModel</param>
26: /// <param name="key">当前项的HtmlName</param>
27: /// <param name="val">当前项的值</param>
28: public static void AddSearchItem(QueryModel model, string key, string val)
29: {
30: string field = "", prefix = "", orGroup = "", method = "";
31: var keywords = key.Split(']', ')', '}');
32: //将Html中的name分割为我们想要的几个部分
33: foreach (var keyword in keywords)
34: {
35: if (Char.IsLetterOrDigit(keyword[0])) field = keyword;
36: var last = keyword.Substring(1);
37: if (keyword[0] == '(') prefix = last;
38: if (keyword[0] == '[') method = last;
39: if (keyword[0] == '{') orGroup = last;
40: }
41: if (string.IsNullOrEmpty(method)) return;
42: if (!string.IsNullOrEmpty(field))
43: {
44: var item = new ConditionItem
45: {
46: Field = field,
47: Value = val.Trim(),
48: Prefix = prefix,
49: OrGroup = orGroup,
50: Method = (QueryMethod) Enum.Parse(typeof (QueryMethod), method)
51: };
52: model.Items.Add(item);
53: }
54: }
55: }
当然我们还要在Global.asax中添加
1: ModelBinders.Binders.Add(typeof (QueryModel), new SearchModelBinder());
这样我们就可以在Action中获取到相应的查询条件了
我们可以看到,从表单提交过来的数据我们已经正确地存放在QueryModel中了。
本节ASP.NET MVC 中使用EF实现自动查询示例就介绍到此。
2011/9/8 19:08:12 | ASP.NET MVC Dev | |