一,repository模式
描述和作用:
按照最初提出者的介绍,它是衔接数据映射层和域之间的一个纽带,作用相当于一个在内存中的域对象集合。客户端对象把查询的一些实体进行组合,并把它们提交给Repository
。对象能够从Repository中移除或者添加,就好比这些对象在一个Collection
对象上就行数据操作,同时映射层的代码会对应的从数据库中取出相应的数据。
从概念上讲,Repository是把一个数据存储区的数据给封装成对象的集合并提供了对这些集合的操作。。。。。。。
在领域驱动设计中,我们有个集合(aggregate
)的概念, 通常我们是对于domain
的每个集合会对应的定义一个repository
。也就说,并不是每个实体都会有对应的一个repository
。(假设这是一个仓库,简介源自网上摘录。。)
二,UnitOfWork模式
描述和作用:
简说了,主要作用是在数据持久化过程中,数据提交,确保数据的完整性,对象使用确保同一上下文对象。如果有异常,提供回滚。
三,二者的关系
即:
工作单元服务于仓储,并在工作单元中初始化上下文,为仓储单元提供上下文对象,由此确保同一上下文对象。
那么此时,问题来了,怎么在仓储中获取上下文。(使用的orm为 EF,以autofac
或者MEF
实现注入,以此为例) 所以,此时实现就变得很简单。
看脚本:
UOW中
在uow中初始化上下文对象,定义了Context
的属性对象(当然,这地方可以不初始化,可以有IOC
在注入时候带入参数注入,详见IOC
,常见方式就几种,实现方式也很类似。) 此处如果看的觉得不爽,换成DbSet
对象也可,您请随意。
repository中
在仓储构造函数中,默认初始化仓储对象和获取上下文对象,好像讲完了,没有了~~~~
以下是本人目前的,我可以说写着玩的吗?就是比较喜爱,但是有弊端,用久了就发觉了,二者组合不是很合适,尽管很多人推崇。当然好处显而易见,就是提供了统一的开发模式和规范,是开发人员的开发方式更具规则性 ,更好维护。
uow:
public OlympicOverDbContext Context
{
get
{
......初始化上下文
}
}
public bool IsCommitted { get;set;}
public int Commit()
{
if (IsCommitted) return 0;
try
{
int result = Context.SaveChanges();
IsCommitted = true;
return result;
}
catch (DbEntityValidationException advEx)
{
...捕捉异常
return -1;
}
}
public void RollBack()
{
IsCommitted = false;
}
public void Dispose()
{
if (!IsCommitted)
{
Commit();
}
Context.Dispose();
}
repository仓储:
public OlympicOverRepository(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
//Context = unitOfWork.GetDbContext;
Context = ((UnitOfWork.UnitOfWork)unitOfWork).Context;
}
#region 属性
/// <summary>
/// 获取仓储上下文的实例
/// </summary>
public IUnitOfWork UnitOfWork
{
get;
}
/// <summary>
/// 数据上下文
/// </summary>
protected DbContext Context
{
get;
private set;
}
/// <summary>
/// 获取 当前实体的查询数据集
/// </summary>
public IQueryable<TEntity> Entities
{
get
{
return Context.Set<TEntity>();
}
}
#endregion
public OlympicOverRepository(IUnitOfWork unitOfWork)
{
UnitOfWork = unitOfWork;
//Context = unitOfWork.GetDbContext;
Context = ((UnitOfWork.UnitOfWork)unitOfWork).Context;
}
#region 属性
/// <summary>
/// 获取仓储上下文的实例
/// </summary>
public IUnitOfWork UnitOfWork
{
get;
}
/// <summary>
/// 数据上下文
/// </summary>
protected DbContext Context
{
get;
private set;
}
/// <summary>
/// 获取 当前实体的查询数据集
/// </summary>
public IQueryable<TEntity> Entities
{
get
{
return Context.Set<TEntity>();
}
}
#endregion
数据仓储模式UnitOfWorks和Repository的实现(
网上看了相关内容关于UnitOfWorks和Repository的数据仓储模式的实现,也来动手搭建下。
ORM使用微软自己的EF来实现
建立一个项目,使用EF,我采用的是DBFirst。建立好连接,连上数据库拖入我要的表,DBFirst有时候还是挺方便的。
然后就要开始实现这个数据仓储模式了
建立泛型接口IUnitOfWorks<TContext>和IRepository<T>
具体实现代码:
public interface IUnitOfWorks<TContext>
{
bool IsCommit { get; set; }//是否自动提交
/// <summary>
/// 设置DbContext上下文
/// </summary>
/// <param name="context"></param>
void SetDb(TContext context);
/// <summary>
/// 获取所有实体对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
IQueryable<T> All<T>() where T : class;
/// <summary>
/// 根据Lamda表达式来查询实体对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="whereLambda"></param>
/// <returns></returns>
IQueryable<T> Where<T>(Expression<Func<T, bool>> whereLambda) where T : class;
/// <summary>
/// 获取所有实体数量
/// </summary>
/// <returns></returns>
int Count<T>() where T : class;
/// <summary>
/// 根据表达式获取实体数量
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
int Count<T>(Expression<Func<T, bool>> whereLambda) where T : class;
/// <summary>
/// 实体对象新增
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
int Add<T>(T model) where T : class;
/// <summary>
/// 实体对象修改
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
int Update<T>(T model) where T : class;
/// <summary>
/// 实体对象根据字段修改
/// </summary>
/// <param name="model"></param>
/// <param name="proName"></param>
/// <returns></returns>
int Update<T>(T model, params string[] proName) where T : class;
/// <summary>
/// 实体对象删除
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
int Delete<T>(T model) where T : class;
/// <summary>
/// 删除复核条件的多个实体对象
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
int Delete<T>(Expression<Func<T, bool>> whereLambda) where T : class;
/// <summary>
/// 修改信息提交
/// </summary>
/// <returns></returns>
int SaveChanges(bool validatonSave = true);
void Dispose();
}
对数据的各种操作
public interface IRepository<T>
where T : class
{
/// <summary>
/// 获取所有实体对象
/// </summary>
/// <returns></returns>
IQueryable<T> All();
/// <summary>
/// 根据Lamda表达式来查询实体对象
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
IQueryable<T> Where(Expression<Func<T, bool>> whereLambda);
/// <summary>
/// 获取所有实体数量
/// </summary>
/// <returns></returns>
int Count();
/// <summary>
/// 根据表达式获取实体数量
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
int Count(Expression<Func<T, bool>> whereLambda);
/// <summary>
/// 实体对象新增
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
int Add(T model, bool IsCommit = false);
/// <summary>
/// 实体对象修改
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
int Update(T model, bool IsCommit = false);
/// <summary>
/// 实体对象根据字段修改
/// </summary>
/// <param name="model"></param>
/// <param name="proName"></param>
/// <returns></returns>
int Update(T model, bool IsCommit=false,params string[] proName);
/// <summary>
/// 实体对象删除
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
int Delete(T model,bool IsCommit=false);
/// <summary>
/// 删除复核条件的多个实体对象
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
int Delete(Expression<Func<T, bool>> whereLambda,bool IsCommit=false);
}
对于IsCommit是否默认提交,设置成可选参数,默认设置成不直接提交需要最终统一提交以实现事务操作。当然也可以直接设置IsCommit为True那么可以单个操作提交.
看起来这两接口是不是挺像的
接下来是这两接口的具体实现
public class Repository<TContext, T> : IRepository<T>
where TContext : DbContext
where T : class
{
protected TContext context;
protected DbSet<T> dbSet;
//protected bool IsCommit;//是否自动提交
protected T entity;
public Repository(TContext dbcontext)
{
context = dbcontext;
dbSet = dbcontext.Set<T>();
}
/// <summary>
/// 获取所有实体对象
/// </summary>
/// <returns></returns>
public IQueryable<T> All()
{
//context.Set<T>().AsQueryable();
return dbSet.AsQueryable();
}
/// <summary>
/// 根据Lamda表达式来查询实体对象
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public IQueryable<T> Where(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
{
return dbSet.Where(whereLambda);
}
/// <summary>
/// 获取所有实体数量
/// </summary>
/// <returns></returns>
public int Count()
{
return dbSet.Count();
}
/// <summary>
/// 根据表达式获取实体数量
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public int Count(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda)
{
return dbSet.Where(whereLambda).Count();
}
/// <summary>
/// 实体对象新增
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Add(T model, bool IsCommit=false)
{
dbSet.Add(model);
int i_flag = IsCommit ? context.SaveChanges() : 0;
return i_flag;
}
/// <summary>
/// 实体对象修改
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Update(T model, bool IsCommit = false)
{
var entry = context.Entry<T>(model);
entry.State = EntityState.Modified;
dbSet.Attach(model);
int i_flag = IsCommit ? context.SaveChanges() : 0;
return i_flag;
}
/// <summary>
/// 实体对象根据字段修改
/// </summary>
/// <param name="model"></param>
/// <param name="proName"></param>
/// <returns></returns>
public int Update(T model, bool IsCommit=false,params string[] proName)
{
var entry = context.Entry<T>(model);
entry.State = EntityState.Unchanged;
foreach (string s in proName)
{
entry.Property(s).IsModified = true;
}
int i_flag = IsCommit ? context.SaveChanges() : 0;
return i_flag;
}
/// <summary>
/// 实体对象删除
/// </summary>
/// <param name="model"></param>
/// <returns></returns
public int Delete(T model,bool IsCommit=false)
{
//var entry = context.Entry<T>(model);
//entry.State = EntityState.Deleted;
dbSet.Attach(model);
dbSet.Remove(model);
int i_flag = IsCommit ? context.SaveChanges() : 0;
return i_flag;
}
/// <summary>
/// 删除复核条件的多个实体对象
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public int Delete(System.Linq.Expressions.Expression<Func<T, bool>> whereLambda,bool IsCommit=false)
{
var enties = dbSet.Where(whereLambda).ToList();
foreach (var item in enties)
{
dbSet.Remove(item);
}
int i_flag = IsCommit ? context.SaveChanges() : 0;
return i_flag;
}
}
public class UnitOfWorks<TContext> : IUnitOfWorks<TContext>
where TContext : DbContext
{
protected TContext dbContext;
protected bool _IsCommit=false;
public bool IsCommit { get { return _IsCommit; } set { _IsCommit = value; } }
public UnitOfWorks()
{
dbContext = (TContext)EFContextFactory.GetDbContext();
}
/// <summary>
/// 设置DbContext上下文
/// </summary>
/// <param name="context"></param>
public void SetDb(TContext context)
{
dbContext = context;
}
private IDictionary<Type, object> RepositoryDic = new Dictionary<Type, object>();
//注册Respository
//public void Register<T>(IRepository<T> respository)
//{
// var key = typeof(T);
// if (RepositoryDic.ContainsKey(key))
// {
// RepositoryDic.Add(key, respository);
// }
//}
protected IRepository<T> GenericRepository<T>() where T : class
{
return new Repository<DbContext, T>(dbContext);
}
public IRepository<T> GetRepository<T>()
where T : class
{
IRepository<T> repository = null;
var key = typeof(T);
if (RepositoryDic.ContainsKey(key))
{
repository = (IRepository<T>)RepositoryDic[key];
}
else
{
repository = GenericRepository<T>();
RepositoryDic.Add(key, repository);
}
return repository;
}
/// <summary>
/// 获取所有实体对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public IQueryable<T> All<T>() where T : class
{
return GetRepository<T>().All();
}
/// <summary>
/// 根据Lamda表达式来查询实体对象
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="whereLambda"></param>
/// <returns></returns>
public IQueryable<T> Where<T>(Expression<Func<T, bool>> whereLambda) where T : class
{
return GetRepository<T>().Where(whereLambda);
}
/// <summary>
/// 获取所有实体数量
/// </summary>
/// <returns></returns>
public int Count<T>() where T : class
{
return GetRepository<T>().Count();
}
/// <summary>
/// 根据表达式获取实体数量
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public int Count<T>(Expression<Func<T, bool>> whereLambda) where T : class
{
return GetRepository<T>().Count(whereLambda);
}
/// <summary>
/// 实体对象新增
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Add<T>(T model) where T : class
{
return GetRepository<T>().Add(model, IsCommit);
}
/// <summary>
/// 实体对象修改
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Update<T>(T model) where T : class
{
return GetRepository<T>().Update(model, IsCommit);
}
/// <summary>
/// 实体对象根据字段修改
/// </summary>
/// <param name="model"></param>
/// <param name="proName"></param>
/// <returns></returns>
public int Update<T>(T model, params string[] proName) where T : class
{
return GetRepository<T>().Update(model,IsCommit, proName);
}
/// <summary>
/// 实体对象删除
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Delete<T>(T model) where T : class
{
return GetRepository<T>().Delete(model, IsCommit);
}
/// <summary>
/// 删除复核条件的多个实体对象
/// </summary>
/// <param name="whereLambda"></param>
/// <returns></returns>
public int Delete<T>(Expression<Func<T, bool>> whereLambda) where T : class
{
return GetRepository<T>().Delete(whereLambda, IsCommit);
}
/// <summary>
/// 修改信息提交
/// </summary>
/// <returns></returns>
public int SaveChanges(bool validatonSave = true)
{
if (!validatonSave)
dbContext.Configuration.ValidateOnSaveEnabled = false;
return dbContext.SaveChanges();
}
public void Dispose()
{
if (dbContext != null)
dbContext.Dispose();
GC.SuppressFinalize(this);
}
}
具体使用方法:
使用IOC的方式,属性注入来实现
public IUnitOfWorks<DbContext> uow { get; set; }
//查询
var query = uow.Where(b=>b.id=="test");
//新增 对表employee进行新增人员
employee empa = new employee();
employee empb = new employee();
empa.id="001";
empa.name="a";
empb.id="002";
empb.name="b";
uow<employee>().add(empa);
uow<employee>().add(empb);
uow.savechange();//实现统一提交
---------------------
作者:Sammy爱学习
来源:CSDN
原文:https://blog.csdn.net/sammy520/article/details/79310864
版权声明:本文为博主原创文章,转载请附上博文链接!