使用了4年的IRepository数据仓储接口,今天要改变了,对于这个数据仓储操作接口,它提倡的是简洁,单纯,就是对数据上下文的操作,而直正的数据上下文本身我们却把它忽略了,在我的IRepository接口里根本没有数据上下文对象,这是不完整的,也许你会说,我使用了基类,数据基类里有数据上下文,是的,我也是那样用的,但有时,这种方法有些死板了,真的,当你碰到IOC时,这种方式的短板就出来了,即,每个反射出来的Repository对象都是独立的,每个对象里的上下文也都是独立的,这是重点,由于上下文是独立的,所以,很多事我们都没法干,这包括<JOIN关联查询,非MSDTC的事务>,看了上面的这么多原因,所以,才决定,扩展我的IRepository接口,当然,严格说,这违背了面向对象的原则,接口不提倡扩展,只提倡新建,呵呵.
全新的IRepository接口
/// <summary>
/// 基础的数据操作规范
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public interface IRepository<TEntity>
where TEntity : class
{
/// <summary>
/// 设定数据上下文,它一般由构架方法注入
/// </summary>
/// <param name="unitOfWork"></param>
void SetDbContext(IUnitOfWork unitOfWork);/// <summary>
/// 添加实体并提交到数据服务器
/// </summary>
/// <param name="item">Item to add to repository</param>
void Insert(TEntity item);/// <summary>
/// 移除实体并提交到数据服务器
/// 如果表存在约束,需要先删除子表信息
/// </summary>
/// <param name="item">Item to delete</param>
void Delete(TEntity item);/// <summary>
/// 修改实体并提交到数据服务器
/// </summary>
/// <param name="item"></param>
void Update(TEntity item);/// <summary>
/// 得到指定的实体集合(延时结果集)
/// Get all elements of type {T} in repository
/// </summary>
/// <returns>List of selected elements</returns>
IQueryable<TEntity> GetModel();/// <summary>
/// 根据主键得到实体
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
TEntity Find(params object[] id);
}
在 DbContext数据基类中的实现
public void SetDbContext(IUnitOfWork unitOfWork)
{
this.Db = (DbContext)unitOfWork;
this.UnitWork = unitOfWork;
}
在IOC中的使用
IUnitOfWork db;
IRepository<Question_Info> question_InfoRepository;
public EFController()
{//反射出仓储对象
db = ServiceLocator.Instance.GetService<IUnitOfWork>();
question_InfoRepository = ServiceLocator.Instance.GetService<IRepository<Question_Info>>();
//为仓储对象设置上下文
question_InfoRepository.SetDbContext(db);
}
在写JOIN查询时,它是被支持的,因为它的数据上下文是同一个