跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(三)Models(ORM、Repository模式、分页)
跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(二)Models(ORM) (9-3 10:43) | |||||
跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(一)数据库建模 (9-1 00:04) |
珍惜他人劳动成果,转载请注明出处,谢谢!
上篇我们已经构建好了EF模型,本篇我们在这个模型的基础上应用Repository模式。
从现在开始,如果你是菜鸟,一定要仔细的慢慢分析啊,这可是接触到核心了啊,呵呵,吓你呢,其实没有那么难。
第一步,我们要把所有的公共操作抽象出来,无外乎我们多次提到的增删改查等操作,这样以后只要继承这个类就可以了。好,首先,我们在Models文件夹下定义一个IRepository接口,这时候,你可能要问:你怎么知道这个接口的类型啊。你别急,我不知道以后要继承的类是什么类型,但我知道它们基本上都有增删改查的功能,这个时候就要用到大名鼎鼎的泛型啦。代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PBAccount.Models
{
public interface IRepository<T>
{
void Add(T entity);
void Del(T entity);
void Update(T entity);
T Find(Guid entityId);
IList<T> Find(ICriteria criteria);
IList<T> FindAll();
IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr);
int Count(ICriteria criteria);
void SaveChanges();
}
}
看看上面的代码,是不是常用的操作都有了啊,你是不是对 IList<T> Find(ICriteria criteria); 这句有点疑惑啊,其实ICriteria using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PBAccount.Models
{
public interface IRepository<T>
{
void Add(T entity);
void Del(T entity);
void Update(T entity);
T Find(Guid entityId);
IList<T> Find(ICriteria criteria);
IList<T> FindAll();
IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr);
int Count(ICriteria criteria);
void SaveChanges();
}
}
是我定义的一个查询条件,我们都知道项目中经常有组合查询,那么多的组合条件,写起来比较麻烦而且非常容易出错,比如起止日期、姓名、地点、金额等一大堆组合条件,写起来确实很累人,这时候我就想到何不定义一个条件类呢。另外,我们现实列表的时候还要用到分页,我们在接口中也写好了这个方法,IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr);厉害吧,你只要填入条件(criteria)、当前页码(page)、每页条数(pageSize)以及排序条件(orderExpr),那么就可以直接分页显示啦。这个在以后你会发现它的极大的优越性,它与JQuery 的flexigrid (类似GridView控件)的分页显示简直就是珠联璧合。下面代码是ICriteria接口 与 Order类的定义。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
namespace PBAccount.Models
{
public interface IRepository<T>
{
void Add(T entity);
void Del(T entity);
void Update(T entity);
T Find(Guid entityId);
IList<T> Find(ICriteria criteria);
IList<T> FindAll();
IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr);
int Count(ICriteria criteria);
void SaveChanges();
}
/// <summary>
/// 查询条件类型
/// </summary>
public enum CriteriaType
{
/// <summary>
/// 0 表示查询条件是个表达式
/// </summary>
Expression = 0,
/// <summary>
/// 1表示查询条件是个参数
/// </summary>
Parameter = 1
}
/// <summary>
/// 查询条件参数类
/// </summary>
public class CriteriaParameter
{
/// <summary>
/// 参数的值
/// </summary>
public object Value { get; private set; }
/// <summary>
/// 参数的名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 参数字段 ?如果你暂时不明白,在以后我们具体使用的时候一看就知道啦,别着急,慢慢来啊
/// </summary>
public string Field { get; private set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <param name="field"></param>
public CriteriaParameter(string name, object value, string field)
{
this.Name = name;
this.Value = value;
this.Field = field;
}
}
/// <summary>
/// 查询条件接口
/// </summary>
public interface ICriteria
{
CriteriaType CriteriaType { get; }
string Expression { get; }
CriteriaParameter[] Parameters { get; }
/// <summary>
/// 并 操作 比如查询“姓名”+“金额” 等
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
ICriteria And(ICriteria other);
ICriteria Or(ICriteria other);
ICriteria Not();
}
/// <summary>
/// 排序类型
/// </summary>
public enum OrderType
{
ASC,
DESC
}
/// <summary>
/// 拍戏类
/// </summary>
public class Order
{
public OrderType OrderType { get; set; }
/// <summary>
/// 排序的字段
/// </summary>
public string[] Fields { get; set; }
public Order(OrderType orderType, params string[] fields)
{
this.OrderType = orderType;
this.Fields = fields;
}
public Order(params string[] fields) : this(OrderType.ASC, fields) { }
/// <summary>
/// 取出排序的表达式
/// </summary>
public string Expression
{
get
{
string str = string.Empty;
foreach (var field in Fields)
{
if (str.Length > 0)
str += ",";
str += string.Format("it.{0} {1}", field, OrderType.ToString());
}
return str;
}
}
/// <summary>
/// 排序 返回 IQueryable<T> 类型的结果
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="query"></param>
/// <returns></returns>
public IQueryable<T> OrderFrom<T>(ObjectQuery<T> query) where T : class
{
switch (this.OrderType)
{
case OrderType.ASC:
return query.OrderBy(Expression);
case OrderType.DESC:
return query.OrderBy(Expression);
}
return query;
}
}
}
以上就是 IRepository接口以及相关的一些类,这里面涉及到得知识就多了一些,虽然有注释,但是如果以前接触很少的话可能看起来还是比较困难,不过不用着急,下面我再介绍一下啊,这里面你要弄懂两个概念,ObjectQuery 和 IQueryable,如果你一点都不明白,那么强烈建议你看看这个using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
namespace PBAccount.Models
{
public interface IRepository<T>
{
void Add(T entity);
void Del(T entity);
void Update(T entity);
T Find(Guid entityId);
IList<T> Find(ICriteria criteria);
IList<T> FindAll();
IList<T> Find(ICriteria criteria, int page, int pageSize, Order orderExpr);
int Count(ICriteria criteria);
void SaveChanges();
}
/// <summary>
/// 查询条件类型
/// </summary>
public enum CriteriaType
{
/// <summary>
/// 0 表示查询条件是个表达式
/// </summary>
Expression = 0,
/// <summary>
/// 1表示查询条件是个参数
/// </summary>
Parameter = 1
}
/// <summary>
/// 查询条件参数类
/// </summary>
public class CriteriaParameter
{
/// <summary>
/// 参数的值
/// </summary>
public object Value { get; private set; }
/// <summary>
/// 参数的名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 参数字段 ?如果你暂时不明白,在以后我们具体使用的时候一看就知道啦,别着急,慢慢来啊
/// </summary>
public string Field { get; private set; }
/// <summary>
/// 构造函数
/// </summary>
/// <param name="name"></param>
/// <param name="value"></param>
/// <param name="field"></param>
public CriteriaParameter(string name, object value, string field)
{
this.Name = name;
this.Value = value;
this.Field = field;
}
}
/// <summary>
/// 查询条件接口
/// </summary>
public interface ICriteria
{
CriteriaType CriteriaType { get; }
string Expression { get; }
CriteriaParameter[] Parameters { get; }
/// <summary>
/// 并 操作 比如查询“姓名”+“金额” 等
/// </summary>
/// <param name="other"></param>
/// <returns></returns>
ICriteria And(ICriteria other);
ICriteria Or(ICriteria other);
ICriteria Not();
}
/// <summary>
/// 排序类型
/// </summary>
public enum OrderType
{
ASC,
DESC
}
/// <summary>
/// 拍戏类
/// </summary>
public class Order
{
public OrderType OrderType { get; set; }
/// <summary>
/// 排序的字段
/// </summary>
public string[] Fields { get; set; }
public Order(OrderType orderType, params string[] fields)
{
this.OrderType = orderType;
this.Fields = fields;
}
public Order(params string[] fields) : this(OrderType.ASC, fields) { }
/// <summary>
/// 取出排序的表达式
/// </summary>
public string Expression
{
get
{
string str = string.Empty;
foreach (var field in Fields)
{
if (str.Length > 0)
str += ",";
str += string.Format("it.{0} {1}", field, OrderType.ToString());
}
return str;
}
}
/// <summary>
/// 排序 返回 IQueryable<T> 类型的结果
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="query"></param>
/// <returns></returns>
public IQueryable<T> OrderFrom<T>(ObjectQuery<T> query) where T : class
{
switch (this.OrderType)
{
case OrderType.ASC:
return query.OrderBy(Expression);
case OrderType.DESC:
return query.OrderBy(Expression);
}
return query;
}
}
}
http://www.it.oaod.com/PcTech-73703.html , 另外也要搞清楚 Entity SQL ,参考 http://tech.ddvip.com/2009-05/1242029734118538.html ,了解一个大概就可以啦。
我们定义了ICriteria,现在我们就要对它实现,我们要在Models中创建一个Criteria类继承ICriteria接口,代码如下:
Code
看到了吧,我们把所有可能的查询条件都给实现啦,以后无论遇到多么复杂的组合查询,我们都不怕啦!OK,现在我们继续,我们在Repository文件夹下创建一个类BaseRepositoryBase.cs,这个类是要继承IRepository接口,实现里面的方法,这样,就把增删查改方法给抽象出来,以后的类只要继承BaseRepositoryBase.cs,就不用自己去实现啦。
本篇结束,请继续阅读 跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(四)Models(ORM、Repository模式、分页