开发笔记:用不用UnitOfWork以及Repository返回什么集合类型
这2天实际开发中明确的东西,在这篇博文中记录一下。
之前对是否需要自己封装UnitOfWork有些犹豫,因为Entity Framework就是一个UnitOfWork实现, 自己再封装一下显得有些多余。
但是在这次开发中,把涉及数据库操作的实现代码放在最后写,先完成其他层的代码。这种情况下,根本用不了EF,只能先Fake出一个UnitOfWork,这时必须要进行UnitOfWork的封装。
所以,定义了IUnitOfWork接口并实现了一个FakeUnitOfWork,简化的示例代码如下:
IUnitOfWork
public interface IUnitOfWork : IDisposable
{
TEntity Add<TEntity>(TEntity entity) where TEntity : class;
Task CommitAsync();
}
FakeUnitOfWork
public class FakeUnitOfWork : IUnitOfWoerk
{
private IList _entities = new List<object>(); public TEntity Add<TEntity>(TEntity entity) where TEntity : class
{
var property = typeof(TEntity).GetProperty("ID");
if(property != null)
{
property.SetValue(entity, new Random().Next());
}
_entities.Add(entity);
return entity;
} public async Task CommitAsync()
{
var bits = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(_entities,
Newtonsoft.Json.Formatting.Indented));
using (var fs = new FileStream(
path: @"C:\temp\FakeUnitOfWork.json",
mode: FileMode.Create,
access: FileAccess.Write,
share: FileShare.None,
bufferSize: ,
useAsync: true))
{
await fs.WriteAsync(bits, , bits.Length);
}
}
}
到写数据库操作代码时,基于EF实现一下IUnitOfWork接口即可。
接下来是Repository返回集合类型的问题。
之前Repository接口多数返回的是IList<T>,这样使用的一个考虑就是让涉及数据库查询的操作尽量在Repository层完成,避免在Application层进行数据库查询操作。
但是今天在Application层的Service中用到了AutoMapper的Project功能,Project的好处是让EF生成的SQL只查询DTO中的字段,但Project扩展方法是针对(且只能针对)IQureryable<T>接口的,所以不得不将Repository接口的返回类型改为IQureryable<T>。
考虑到Project的巨大吸引力以及为了保持Repository返回类型的一致,以后Repository就都统一返回IQureryable<T>吧。
示例代码如下:
IBlogCategoryRepository
public interface IBlogCategoryRepository
{
Task<IQueryable<BlogCategory>> GetCategoriesByBlogId(int blogId, bool activeOnly);
}
BlogCategoryService
public class BlogCategoryService : IBlogCategoryService
{
private IBlogCategoryRepository _blogCategoryRepository; public BlogCategoryServiceImp(IBlogCategoryRepository blogCategoryRepository)
{
_blogCategoryRepository = blogCategoryRepository;
} async Task<IList<BlogCategoryDto>> IBlogCategoryService.GetCategoriesByBlogId(int blogId, bool activeOnly)
{
return (await _blogCategoryRepository
.GetCategoriesByBlogId(blogId, activeOnly))
.Project()
.To<BlogCategoryDto>()
.ToList();
}
}
开发笔记:用不用UnitOfWork以及Repository返回什么集合类型的更多相关文章
- Programming In Scala笔记-第十七章、Scala中的集合类型
本章主要介绍Scala中的集合类型,主要包括:Array, ListBuffer, Arraybuffer, Set, Map和Tuple. 一.序列 序列类型的对象中包含多个按顺序排列好的元素,可以 ...
- Yocto开发笔记之《Tip-stdlib库函数strtod返回nan错误》(QQ交流群:519230208)
2015.04-imx_v2015.04_3.14.38_6ul_ga+g5d63276 (Jan 04 2016 - 18:07:08) FSL Community BSP : https://co ...
- 开发笔记:基于EntityFramework.Extended用EF实现指定字段的更新
今天在将一个项目中使用存储过程的遗留代码迁移至新的架构时,遇到了一个问题——如何用EF实现数据库中指定字段的更新(根据UserId更新Users表中的FaceUrl与AvatarUrl字段)? 原先调 ...
- Repository 返回 IQueryable?还是 IEnumerable?
这是一个很有意思的问题,我们一步一步来探讨,首先需要明确两个概念(来自 MSDN): IQueryable:提供对未指定数据类型的特定数据源的查询进行计算的功能. IEnumerable:公开枚举数, ...
- 项目架构开发:数据访问层之Repository
接上文 项目架构开发:数据访问层之Logger 本章我们继续IRepository开发,这个仓储与领域模式里边的仓储有区别,更像一个工具类,也就是有些园友说的“伪仓储”, 这个仓储只实现单表的CURD ...
- 【转】Repository 返回 IQueryable?还是 IEnumerable?
这是一个很有意思的问题,我们一步一步来探讨,首先需要明确两个概念(来自 MSDN): IQueryable:提供对未指定数据类型的特定数据源的查询进行计算的功能. IEnumerable:公开枚举数, ...
- 李兴华JavaWeb开发笔记
李兴华JavaWeb开发笔记 1.Java语法-基础 环境变量-JAVA_HOME, PATH, ClassPath 变量名 作用 举例 JAVA_HOME 指向JDK目录 C:\Program Fi ...
- Java开发笔记(八十六)通过缓冲区读写文件
前面介绍了利用文件写入器和文件读取器来读写文件,因为FileWriter与FileReader读写的数据以字符为单位,所以这种读写文件的方式被称作“字符流I/O”,其中字母I代表输入Input,字母O ...
- Java开发笔记(五十六)利用枚举类型实现高级常量
前面介绍了联合利用final和static可实现常量的定义,该方式用于简单的常量倒还凑合,要是用于复杂的.安全性高的常量,那就力不从心了.例如以下几种情况,final结合static的方式便缺乏应对之 ...
随机推荐
- WPF 自定义控件
在实际工作中,面对不同的客户需求,需要让空间显示出不同的效果.当style已经不能足够满足客户需求时,就需要程序猿自己设计自定义控件了. 根据工作经历,LZ做了个关于自定义控件的小Demo,仅供参考. ...
- docker进程管理
docker进程管理:http://www.open-open.com/lib/view/open1455412749917.html 写的太好!!!!示例很清楚,很全面!! 我做个summary吧. ...
- C/C++关键字 extern
1.基本解释:extern 可置于变量或函数前面,表示变量或函数的定义在别的文件中,以提示编译器遇到此变量或函数时在其他模块中寻找定义. extern还有另外2个作用.第一:与“C”连用时,如 ext ...
- UI自动化测试的那些事
互联网产品的迭代速度远高于传统软件,尤其是移动APP不但更新频繁,还需要在不同硬件.系统版本的环境下进行大量兼容测试,这就给传统测试方法和测试工具带来了巨大挑战.为满足产品敏捷开发.快速迭代的需求,自 ...
- 1032 - A-B 组合数学
http://www.ifrog.cc/acm/problem/1032 1032 - A-B Time Limit:1s Memory Limit:128MByte Submissions:680S ...
- Android自动化预备(下)
上次说道:要具备的一些知识,还有多ADB得理解 本次继续ADB理解: AndroidDebugBridge debugBridge =AndroidDebugBridge.createBridge(& ...
- PostGreSQL存储过程
1 返回结果集的存储过程 -- drop FUNCTION getall();CREATE or REPLACE FUNCTION getall() RETURNS SETOF users AS$B ...
- $watch监听数据变化和run方法
angular中$watch方法可以监听数据的变化. $scope.$watch('phone',function(){ $scope.phone.fre = $scope.phone.num> ...
- python 中 深拷贝和浅拷贝的理解
在总结 python 对象和引用的时候,想到其实 对于python的深拷贝和浅拷贝也可以很好对其的进行理解. 在python中,对象的赋值的其实就是对象的引用.也就是说,当创建一个对象,然后赋给另外一 ...
- firemonkey中stringgrid属性大全
StringGrid之属性大全: Align: //确定组件在父类组件区内的对齐方式(alScale:随窗口 放大缩小) AlterRowBack ...