关于EF Unit of Work Repository的简单用法
其实ef本身就是unit of work+repository的
其中继承自DbContext的类就是unit of work
context中的DbSet<T>属性就是repository,你也可以不建那些属性,而使用context.Set<T>来获取一个DbSet<T>
如果直接在逻辑层就ef了,一来可能觉得会与ef绑的太紧,二来可能mock的难度会变大。所以有时候还是希望逻辑层引用的是自己定义的unit of work接口和repository接口
先来看这两个接口吧
public interface IUnitOfWork
{
IRepository<T> GetRep<T>() where T : class; int Comment();
} public interface IRepository<T> : IQueryable<T>
where T : class
{
T Add(T obj);
}
repository我只写了一个add方法做为说明,你可以写更多的方法
public class DatabaseContext : DbContext, IUnitOfWork
{
public IRepository<T> GetRep<T>() where T : class
{
return null;
} public int Comment()
{
return this.SaveChanges();
}
}
建一个ef的context,继承DbContext的同时,实现IUnitOfWork
其中的comment方法,直接调用ef的savechanges,其实要是偷懒,直接把接口里的comment命名成savechanges就完事
剩下就是得实现这个getrep<T>的方法了。
我们对外提供的是IRepository,而我们有的是ef的DbSet,俩边接口不匹配,祭出适配器模式。
public class RepositoryAdapter<T> : IRepository<T>
where T : class
{
private DbContext context; private IDbSet<T> set; public RepositoryAdapter(DbContext context, IDbSet<T> set)
{
this.context = context;
this.set = set;
}
……
建一个适配器类,构造的时候接收context和dbset
之后,我们要实现IRepository的方法
public T Add(T obj)
{
return set.Add(obj);
}
把他导向到dbset的方法去即可
因为,我们的IRepository是集成了IQueryable的,还得实现这些
public IEnumerator<T> GetEnumerator()
{
return set.GetEnumerator();
} IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
} public Expression Expression
{
get
{
return set.Expression;
}
} public Type ElementType
{
get
{
return set.ElementType;
}
} public IQueryProvider Provider
{
get
{
return set.Provider;
}
}
统统导向到dbset的方法去
我们让context的方法返回这个适配器
public IRepository<T> GetRep<T>() where T : class
{
return new RepositoryAdapter<T>(this, this.Set<T>());
}
使用是uow.GetRep<T>().Where(x=>x…….)各种where,first,count,any,只要是IQueryable支持的都可以正常使用
并且根据你IRepository中定义的方法,还可以add,delete之类的
但是有一个ef的方法在这里是不行的,那就是Include。
普通的where之类的方法,看源码
他是用source的provider去走。
这里,source是我们的IRepository,实际是RepositoryAdapter,adapter中的provider,我们返回的是dbset的provider,所以他可以正常的走到dbset去查库
但是,我们看include
include 并没有走provider,而是要看source是不是DbQuery<T>或者ObjectQuery<T>,我们这里自然都不是,所以include没能正确的导向到dbset的include去
我们可以自己写一个扩展方法
public static IQueryable<T> Include<T>(this IRepository<T> source, string path) where T : class
{
var s = source as RepositoryAdapter<T>;
if (s != null)
{
return s.Set.Include(path);
}
return source;
}
为了能访问到source的dbset,我们得把dbset用只读属性公开出来。
这样,我们就可以正确的把include也导向到dbset的include了。
如果你要换orm了,你需要为新的orm开发对应的适配器类
关于EF Unit of Work Repository的简单用法的更多相关文章
- Unit of work + Repository
(Unit of work + Repository) 今日后开启进阶模式! 谈到MVC与EntityFramework,则不得不说一说事务与仓储(Unit of work + Repository) ...
- .NET MVC4 实训记录之四(Unit of work + Repository)
今日后开启进阶模式! 谈到MVC与EntityFramework,则不得不说一说事务与仓储(Unit of work + Repository). 仓储(Repository):领域对象集合.用于操作 ...
- [转]Upgrading to Async with Entity Framework, MVC, OData AsyncEntitySetController, Kendo UI, Glimpse & Generic Unit of Work Repository Framework v2.0
本文转自:http://www.tuicool.com/articles/BBVr6z Thanks to everyone for allowing us to give back to the . ...
- spring boot: @Entity @Repository一个简单的数据读存储读取
spring boot: @Entity @Repository一个简单的数据读存储读取 创建了一个实体类. 如何持久化呢?1.使用@Entity进行实体类的持久化操作,当JPA检测到我们的实体类当中 ...
- EMCA和EMCTL的简单用法
背景 其实这两个完全是两回事,不过倒是有关系,emca就是建立的资料库,建立后就用emctl来管理服务了.oem有问题基本都是重建emca,然后用emctl来操作. 当时用emca感觉真是一阵空白,太 ...
- centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件、目录属性 shell数组简单用法 $( ) 和${ } 和$(( )) 与 sh -n sh -x sh -v 第三十五节课
centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件.目录属性 shell数组简单用法 $( ) 和$ ...
- CATransition(os开发之画面切换) 的简单用法
CATransition 的简单用法 //引进CATransition 时要添加包“QuartzCore.framework”,然后引进“#import <QuartzCore/QuartzCo ...
- jquery.validate.js 表单验证简单用法
引入jquery.validate.js插件以及Jquery,在最后加上这个插件的方法名来引用.$('form').validate(); <!DOCTYPE html PUBLIC " ...
- NSCharacterSet 简单用法
NSCharacterSet 简单用法 NSCharacterSet其实是许多字符或者数字或者符号的组合,在网络处理的时候会用到 NSMutableCharacterSet *base = [NSMu ...
随机推荐
- 详解webpack + vue + node 打造单页面(入门篇)
1.node下载地址:http://nodejs.cn/download/,安装完成检查node和npm版本 2.淘宝镜像 : npm install cnpm -g --registry=https ...
- .net core初试 --- 控制台程序
.net core这个名字对.net程序员来说都不陌生了,但貌似圈子里真正有开发经验的并不多,关键是公司的项目没需求. 今天我就趁着不忙上手玩了玩,搞明白了一些东西,心中也有了十万个为什么.那么现在与 ...
- SSRS (一)创建基础报表
ReportService创建基础报表 1.数据库SQL Server2012选择SQL Server Data Tools 2.创建商业智能(BI)项目 选择报表服务器项目 ReportServic ...
- Docker之存储管理
本文由作者邹珍珍授权网易云社区发布. 本文主要介绍Docker的存储管理.Docker拥有镜像分层,写时复制机制以及内容寻址存储等特征,为了支持这些特征,Docker设计了一套镜像元数据管理机制来管理 ...
- 深度优先搜索 - 简单demo
输入一个数n,输出 1 ~ n 的全排列,例如输入 3,全排列则为:123,132,213,231,312,321 一共六种. 这里采用深度优先搜索来解决这个问题: #include<stdio ...
- 匹配img标签的正则表达式
$preg = '/<img.*?src=[\"|\']?(.*?)[\"|\']?\s.*?>/i';//匹配img标签的正则表达式 preg_match_all($ ...
- git忽略掉文件权限检查
有时 git diff 执行显示文件内容没变化,但是有 old mode xxx new mode,原因是文件的权限,被chmod变化了,这种变化也被 diff 识别出来了,让git忽略掉文件权限检查 ...
- php 类继承
%token T_EXTENDS "extends (T_EXTENDS)" unticked_class_declaration_statement: class_entry_t ...
- 原生js 实现jquery addClass,removeClass
代码如下: function hasClass(obj, cls) { let reg = new RegExp("(\\s|^)" + cls + "(\\s|$)&q ...
- MySQL命令行导入sql文件时出现乱码解决方案
Note: sql> source F:weibo.sql(执行相关sql文件) sql> select * from sina into outfile "/weibo.txt ...