直奔主题了,不那么啰嗦。

一下分三个步骤说明,分别为 dbContext,repository,uow三点

在说之前,先说下O# 因为最近发现还有人在问,其实很好理解,简要说下理解步骤(O#的整体框架和上面的截图类似->_->我就是仿照的o#搭建的好不好)

如果对respository+uow熟练的人 ,一下就能看懂

看图一,图中的Core.Data.Entity

说实话,我也偷懒了,以下是 IRepository和IUnitofWork的定义

IRepository:

/// <summary>
/// 实现仓储模型的数据标准操作
/// </summary>
public interface IRepository<TEntity> : IDependency
{
#region 属性
/// <summary>
/// 获取 当前单元操作对象
/// </summary>
IUnitOfWork UnitOfWork { get; }
/// <summary>
/// 获取当前实体查询数据集,数据将使用不跟踪变化的方式来查询
/// </summary>
IQueryable<TEntity> Entites { get; } #endregion #region 方法
/// <summary>
/// 插入实体
/// </summary>
/// <param name="entity">实体对象</param>
/// <returns>操作影响的行数</returns>
int Insert(TEntity entity, bool save = true); /// <summary>
/// 批量插入实体
/// </summary>
/// <param name="entities">实体对象集合</param>
/// <returns>操作影响的行数</returns>
int Insert(IEnumerable<TEntity> entities, bool save = true); /// <summary>
/// 删除实体
/// </summary>
/// <param name="entity">实体对象</param>
/// <returns>操作影响的行数</returns>
int Delete(TEntity entity, bool save = true); /// <summary>
/// 删除指定编号的实体
/// </summary>
/// <param name="key">实体主键</param>
/// <returns>操作影响的行数</returns>
int Delete(object key, bool save = true); /// <summary>
/// 删除所有符合特定条件的实体
/// </summary>
/// <param name="predicate">查询条件谓语表达式</param>
/// <returns>操作影响的行数</returns>
int Delete(Expression<Func<TEntity, bool>> predicate, bool save = true); /// <summary>
/// 批量删除实体
/// </summary>
/// <param name="entities">实体对象集合</param>
/// <returns>操作影响的行数</returns>
int Delete(IEnumerable<TEntity> entities, bool save = true); /// <summary>
/// 更新指定主键的对象
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
int Update(object key, bool save = true); /// <summary>
/// 更新实体对象
/// </summary>
/// <param name="entity">更新后的实体对象</param>
/// <returns>操作影响的行数</returns>
int Update(TEntity entity, bool save = true);
/// <summary>
/// 批量更新数据
/// </summary>
/// <param name="entites">对象集合</param>
/// <returns></returns>
int Update(IEnumerable<TEntity> entites, bool save = true);
///// <summary>
///// 检查实体是否存在
///// </summary>
///// <param name="predicate">查询条件谓语表达式</param>
///// <param name="id">编辑的实体标识</param>
///// <returns>是否存在</returns>
//bool CheckExists(Expression<Func<TEntity, bool>> predicate, object id); /// <summary>
/// 查找指定主键的实体
/// </summary>
/// <param name="key">实体主键</param>
/// <returns>符合主键的实体,不存在时返回null</returns>
TEntity GetByKey(object key); /// <summary>
/// 查询指定条件的实体
/// </summary>
/// <param name="predicate">查询表达式</param>
/// <returns>符合条件的实体集合</returns>
IEnumerable<TEntity> GetByPredicate(Expression<Func<TEntity, bool>> predicate); /// <summary>
/// 获取贪婪加载导航属性的查询数据集
/// </summary>
/// <param name="path">属性表达式,表示要贪婪加载的导航属性</param>
/// <returns>查询数据集</returns>
IQueryable<TEntity> GetInclude<TProperty>(Expression<Func<TEntity, TProperty>> path); /// <summary>
/// 获取贪婪加载多个导航属性的查询数据集
/// </summary>
/// <param name="paths">要贪婪加载的导航属性名称数组</param>
/// <returns>查询数据集</returns>
IQueryable<TEntity> GetIncludes(params string[] paths); /// <summary>
/// 创建一个原始 SQL 查询,该查询将返回此集中的实体。
/// 默认情况下,上下文会跟踪返回的实体;可通过对返回的 DbRawSqlQuery 调用 AsNoTracking 来更改此设置。 请注意返回实体的类型始终是此集的类型,而不会是派生的类型。 如果查询的一个或多个表可能包含其他实体类型的数据,则必须编写适当的 SQL 查询以确保只返回适当类型的实体。 与接受 SQL 的任何 API 一样,对任何用户输入进行参数化以便避免 SQL 注入攻击是十分重要的。 您可以在 SQL 查询字符串中包含参数占位符,然后将参数值作为附加参数提供。 您提供的任何参数值都将自动转换为 DbParameter。 context.Set(typeof(Blog)).SqlQuery("SELECT * FROM dbo.Posts WHERE Author = @p0", userSuppliedAuthor); 或者,您还可以构造一个 DbParameter 并将它提供给 SqlQuery。 这允许您在 SQL 查询字符串中使用命名参数。 context.Set(typeof(Blog)).SqlQuery("SELECT * FROM dbo.Posts WHERE Author = @author", new SqlParameter("@author", userSuppliedAuthor));
/// </summary>
/// <param name="trackEnabled">是否跟踪返回实体</param>
/// <param name="sql">SQL 查询字符串。</param>
/// <param name="parameters">要应用于 SQL 查询字符串的参数。 如果使用输出参数,则它们的值在完全读取结果之前不可用。 这是由于 DbDataReader 的基础行为而导致的,有关详细信息,请参见 http://go.microsoft.com/fwlink/?LinkID=398589。</param>
/// <returns></returns>
IEnumerable<TEntity> SqlQuery(string sql, bool trackEnabled = true, params object[] parameters); /// <summary>
/// 分页数据查询
/// </summary>
/// <param name="pageCondition">分页和排序条件</param>
/// <param name="predicate">数据过滤条件 表达式</param>
/// <returns>分页后的数据集合</returns>
IQueryable<TEntity> Get(PageCondition pageCondition, Expression<Func<TEntity, bool>> predicate, out int totalRow); #endregion }

IUnitOfWork:

/// <summary>
///
/// </summary>
public interface IUnitOfWork: IDependency, IDisposable
{ #region 方法
/// <summary>
/// 命令提交
/// </summary>
/// <returns>提交操作结果</returns>
int SaveChanges(bool save); DbContext DbContext { get; }
#endregion }

此处之所以这么定义(只有两个对象),看上一篇关于 repository和uow的关系

对应的repository和uow的实现
repository:

/// <summary>
/// 仓储
/// </summary>
public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
#region Fields
private readonly IUnitOfWork _unitOfWork;
private readonly DbSet<TEntity> _dbSet;
#endregion #region ctor
/// <summary>
/// 初始化一个<see cref="Repository{TEntity}"/>类型的新实例
/// </summary>
public Repository(IUnitOfWork unitOfWork)
{
this._unitOfWork = unitOfWork;
this._dbSet = _unitOfWork.DbContext.Set<TEntity>();
}
#endregion #region 属性
/// <summary>
/// 获取 当前实体类型的查询数据集,数据将使用不跟踪变化的方式来查询
/// </summary>
public IQueryable<TEntity> Entites { get { return _dbSet.AsNoTracking(); } }
/// <summary>
/// 获取 当前单元操作对象
/// </summary>
public IUnitOfWork UnitOfWork { get { return _unitOfWork; } } #endregion #region 方法 ///// <summary>
///// 判断指定表达式条件 的对象是否存在
///// </summary>
///// <param name="predicate"></param>
///// <param name="id"></param>
///// <returns></returns>
//public bool CheckExists(Expression<Func<TEntity, bool>> predicate, object id)
//{
// var entity = _dbSet.Where(predicate).Select(m => )
//}
/// <summary>
/// 删除所有符合特定条件的实体
/// </summary>
/// <param name="predicate">查询条件谓语表达式</param>
/// <returns>操作影响的行数</returns>
public int Delete(Expression<Func<TEntity, bool>> predicate, bool save = true)
{
var entities = _dbSet.Where(predicate).AsEnumerable();
if (null != entities && entities.Count() > )
{
_dbSet.RemoveRange(entities);
}
return _unitOfWork.SaveChanges(save);
}
/// <summary>
/// 批量删除实体
/// </summary>
/// <param name="entities">实体对象集合</param>
/// <returns>操作影响的行数</returns>
public int Delete(IEnumerable<TEntity> entities, bool save = true)
{
if (null != entities && entities.Count() > )
{
_dbSet.RemoveRange(entities);
}
return _unitOfWork.SaveChanges(save);
} public int Delete(object key, bool save = true)
{
var entity = _dbSet.Find(key);
_dbSet.Remove(entity);
return _unitOfWork.SaveChanges(save);
} public int Delete(TEntity entity, bool save = true)
{
_dbSet.Remove(entity);
return _unitOfWork.SaveChanges(save);
} public TEntity GetByKey(object key)
{
return _dbSet.Find(key);
} public IEnumerable<TEntity> GetByPredicate(Expression<Func<TEntity, bool>> predicate)
{
return _dbSet.Where(predicate).AsEnumerable();
} public IQueryable<TEntity> GetInclude<TProperty>(Expression<Func<TEntity, TProperty>> path)
{
return _dbSet.Include(path);
} public IQueryable<TEntity> GetIncludes(params string[] paths)
{
IQueryable<TEntity> sources = null;
foreach (var path in paths)
{
sources = _dbSet.Include(path);
}
return sources;
} public int Insert(IEnumerable<TEntity> entities, bool save = true)
{
_dbSet.AddRange(entities);
return _unitOfWork.SaveChanges(save);
} public int Insert(TEntity entity, bool save = true)
{
_dbSet.Add(entity);
return _unitOfWork.SaveChanges(save);
} public IEnumerable<TEntity> SqlQuery(string sql, bool trackEnabled = true, params object[] parameters)
{
return trackEnabled
? _dbSet.SqlQuery(sql, parameters)
: _dbSet.SqlQuery(sql, parameters).AsNoTracking();
} public int Update(object key, bool save = true)
{
var entity = _dbSet.Find(key);
return Update(entity, save);
} public int Update(TEntity entity, bool save = true)
{
DbContext context = ((DbContext)_unitOfWork); DbSet<TEntity> dbSet = context.Set<TEntity>();
try
{
DbEntityEntry<TEntity> entry = context.Entry(entity);
if (entry.State == EntityState.Detached)
{
dbSet.Attach(entity);
entry.State = EntityState.Modified;
}
}
catch (InvalidOperationException ex)
{
throw new Exception(ex.Message);
}
return _unitOfWork.SaveChanges(save);
} public int Update(IEnumerable<TEntity> entites, bool save = true)
{
DbContext context = ((DbContext)_unitOfWork); DbSet<TEntity> dbSet = context.Set<TEntity>(); foreach (var entity in entites)
{
try
{
DbEntityEntry<TEntity> entry = context.Entry(entity);
if (entry.State == EntityState.Detached)
{
dbSet.Attach(entity);
entry.State = EntityState.Modified;
}
}
catch (InvalidOperationException ex)
{
throw new Exception(ex.Message);
}
} return _unitOfWork.SaveChanges(save);
} public IQueryable<TEntity> Get(PageCondition pageCondition, Expression<Func<TEntity, bool>> predicate, out int totalRow)
{
int totalCount = ;
IQueryable<TEntity> source = _dbSet.Where(predicate);
if (pageCondition.SortConditions == null || pageCondition.SortConditions.Length == )
{
source = source.OrderBy("Id");
}
else
{
int count = ;
IOrderedQueryable<TEntity> orderSource = null;
foreach (SortCondition sortCondition in pageCondition.SortConditions)
{
orderSource = count ==
? CollectionPropertySorter<TEntity>.OrderBy(source, sortCondition.SortField, sortCondition.ListSortDirection)
: CollectionPropertySorter<TEntity>.ThenBy(orderSource, sortCondition.SortField, sortCondition.ListSortDirection);
count++;
}
source = orderSource;
totalCount = source.Count();
}
int pageIndex = pageCondition.PageIndex, pageSize = pageCondition.PageSize;
source = source != null
? source.Skip((pageIndex - ) * pageSize).Take(pageSize)
: Enumerable.Empty<TEntity>().AsQueryable();
//IQueryable<TResult> query = source.Select(selector);
//return GetKey(query.Expression);
totalRow = totalCount;
return source;
} #endregion }

uow:

/// <summary>
/// 工作单元实现
/// </summary>
public class UnitOfWork : IUnitOfWork
{
private bool _disposed;
private DbContext _dbContext; public UnitOfWork()
{
this._dbContext = DbContext;
} /// <summary>
/// 数据提交操作
/// </summary>
/// <returns></returns>
public int SaveChanges(bool save)
{
if (save)
{
try
{
try
{
return _dbContext.SaveChanges();
}
catch (DbEntityValidationException dbex)
{ throw;
}
}
catch (Exception ex)
{ throw;
}
}
return ;
} public DbContext DbContext
{
get
{
//CallContext:是线程内部唯一的独用的数据槽(一块内存空间)
//传递DbContext进去获取实例的信息,在这里进行强制转换。
DbContext dbContext = CallContext.GetData("DbContext") as DbContext;
if (dbContext == null) //线程在数据槽里面没有此上下文
{
dbContext = new InnovatorContext(); //如果不存在上下文的话,创建一个EF上下文
//我们在创建一个,放到数据槽中去
CallContext.SetData("DbContext", dbContext);
}
return dbContext;
}
} public virtual void Dispose(bool disposing)
{
if (!this._disposed)
if (disposing)
this._dbContext.Dispose(); this._disposed = true;
} public void Dispose()
{
Dispose(true);
}
}

脚本中涉及到的 SortDirection源自O#的干货中的实现,具体参见 o#

至此,该内容已完毕,以上实现院子处处有,再说闲的多余了。

mvc5 + ef6 + autofac搭建项目(repository+uow)(一)的更多相关文章

  1. mvc5 + ef6 + autofac搭建项目(repository+uow)(二)

    续上篇: DBContext 在上篇 图一类库根目录创建的 DbContextBase /// <summary> /// 数据库上下文基类 /// </summary> // ...

  2. mvc5 + ef6 + autofac搭建项目(三)

    前面已经基本完成了框架的搭建,后面就是实现了,后面主要说下前端的东西bootstrap的使用和相关插件. 看图: 实现比较简单,在主页面只引入共用部分的 js等相关包,毕竟不是所有页面都需要列表以及其 ...

  3. mvc5 + ef6 + autofac搭建项目(四).1视屏上传生成截图

    即上一篇中上传涉及到的 一个视频生成截图的问题,这个很简单,这是上一篇中的代码片段 #region 视频上传,生成默认展示图片(自动剪切) try { string fileSavePath = Da ...

  4. mvc5 + ef6 + autofac搭建项目(四)

    在列表页面,点击新增,弹出窗口实现视屏上传,这里存在一个问题,就是大文件上传的问题,iis出于安全问题,有限制,当然这不是大问题,解决也很容易: 见截图: 请忽略视屏文件,看得懂的请装作不懂. 源码 ...

  5. MVC5+EF6 简易版CMS(非接口) 第一章:新建项目

    目录 简易版CMS后台管理系统开发流程 MVC5+EF6 简易版CMS(非接口) 第一章:新建项目 MVC5+EF6 简易版CMS(非接口) 第二章:建数据模型 MVC5+EF6 简易版CMS(非接口 ...

  6. mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理

    1.mvc5+ef6+Bootstrap 项目心得--创立之初 2.mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理 3.mvc5+ef6+Bootstrap 项目心得--WebG ...

  7. mvc5+ef6+Bootstrap 项目心得--WebGrid

    1.mvc5+ef6+Bootstrap 项目心得--创立之初 2.mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理 3.mvc5+ef6+Bootstrap 项目心得--WebG ...

  8. mvc5+ef6+Bootstrap 项目心得--创立之初

    1.mvc5+ef6+Bootstrap 项目心得--创立之初 2.mvc5+ef6+Bootstrap 项目心得--身份验证和权限管理 3.mvc5+ef6+Bootstrap 项目心得--WebG ...

  9. mvc项目架构分享系列之架构搭建之Repository和Service

    项目架构搭建之Repository和Service的搭建 Contents 系列一[架构概览] 0.项目简介 1.项目解决方案分层方案 2.所用到的技术 3.项目引用关系 系列二[架构搭建初步] 4. ...

随机推荐

  1. Docker在云环境中的应用实践初探:优势、局限性与效能评测

    作者 商之狄 发布于 2014年11月10日 本文依据笔者所在团队的一些近期开发和应用的实践,整理出一些有意义的信息,拿出来和社区分享.其中既包括在云端应用Docker与相关技术的讨论,同时也有实施过 ...

  2. (转载)php循环检测目录是否存在并创建(循环创建目录)

    (转载)http://www.jb51.net/article/25917.htm php循环检测目录是否存在并创建,需要的朋友可以参考下. 循环创建目录方法 这个会生成image.gif目录 代码如 ...

  3. Devexpress之dxErrorProvider

    DXErrorProvider:错误提示控件,用法类似于VS的winform控件中的ErrorProvider. 下面为一个使用实例,验证文本框输入是否为数字: ①.添加System.Text.Reg ...

  4. Selenium WebDriver + Grid2 + RSpec之旅(二)----Grid2的配置

    Selenium WebDriver + Grid2 + RSpec之旅(二) ----Grid2的配置 为什么要使用Selenium-Grid 分布式运行大规模的TestCase 能够通过一个中央节 ...

  5. 笔记本CPU的型号和类型的区分方法

    笔记本CPU的型号和类型的区分方法: 1.所有笔记本CPU型号后面默认为M,代表移动版. 2.如果M变为H,则代表高性能版本,时钟频率更高,性能强,但功耗更大一点,如I7 4500H. 3.如果M变为 ...

  6. 在net安装程序中部署oracle客户端全攻略

    在net安装程序中部署oracle客户端全攻略 主要的是要做三件工作: 打包文件,写注册表,注册环境变量说明:我的oracle版本为9, 在2000 advanced server 上测试通过,可以正 ...

  7. glsl-UBO

    UBO 是什么?为何要用UBO? 1.数据共享设计 采用Block的原因是: 如果你的程序中包含了多个着色器,而且这些着色器使用了相同的Uniform变量,你就不得不为每个着色器分别管理这些变量.Un ...

  8. Windows 8.1中怎么启用Framework3.5或2.0 ( 一安装就跳到下载 Win8.1自带了Framework)

    Windows 8.1中怎么启用Framework3.5或2.0      ( 一安装就跳到下载 Win8.1自带了Framework): Win+X键 打开   开始菜单 -> 命令提示符(管 ...

  9. 1116 HTML CSS

    1. JPEG和GIF在使用时的注意事项: JPEG可以连续调次(复制品中有中间层次,如照片)图像中获得最好效果:JPEG可以用1600万色显示图像,是有损格式,不支持透明. GIF适用于几种纯色组成 ...

  10. 【python自动化第七篇:面向对象进阶】

    知识点概览: 静态方法,类方法,属性方法 类的特殊方法 反射 异常处理 socket开发基础 一.静态方法:@staticmethod 只是名义上归类管理,实际上在静态方法里访问不了类或者实例中的任何 ...