DDD-EF-数据仓储
转载来源 https://www.cnblogs.com/frozenzhang/p/5390551.html
关系图
一、分层
二、DomainObjects构建edmx
三、EFRepositoryDemo.Domain定义仓储接口
1 public interface IRepository<T> 2 where T : class 3 { 4 void Add(T entity); 5 void AddAll(IEnumerable<T> entities); 6 void Update(T entity); 7 void Update(IEnumerable<T> entities); 8 void Delete(T entity); 9 void Delete(Expression<Func<T, bool>> where); 10 void DeleteAll(IEnumerable<T> entities); 11 12 void Clear(); 13 T GetById(long Id); 14 T GetById(string Id); 15 T Get(Expression<Func<T, bool>> where); 16 IEnumerable<T> GetAll(); 17 IEnumerable<T> GetMany(Expression<Func<T, bool>> where); 18 IEnumerable<T> GetAllLazy(); 19 }
四、Infrastructure层 仓储的抽象基类(EF的CRUD)
Repository很明显的一个特征 是 内部没有SaveChanges()
1 public abstract class EFRepositoryBase<T> where T : class 2 { 3 private Db1DbContext dataContext; 4 private readonly DbSet<T> dbset; 5 6 protected IDatabaseFactory DatabaseFactory 7 { 8 get; 9 private set; 10 } 11 12 protected Db1DbContext DataContext 13 { 14 get { return dataContext ?? (dataContext = DatabaseFactory.Get()); } 15 } 16 17 protected EFRepositoryBase(IDatabaseFactory databaseFactory) 18 { 19 DatabaseFactory = databaseFactory; 20 dbset = DataContext.Set<T>(); 21 } 22 23 public virtual void Add(T entity) 24 { 25 dbset.Add(entity); 26 } 27 28 //新增方法 29 public virtual void AddAll(IEnumerable<T> entities) 30 { 31 dbset.AddRange(entities); 32 } 33 34 public virtual void Update(T entity) 35 { 36 dbset.Attach(entity); 37 dataContext.Entry(entity).State = EntityState.Modified; 38 } 39 40 //新增方法 41 public virtual void Update(IEnumerable<T> entities) 42 { 43 foreach (T obj in entities) 44 { 45 dbset.Attach(obj); 46 dataContext.Entry(obj).State = EntityState.Modified; 47 } 48 } 49 50 public virtual void Delete(T entity) 51 { 52 dbset.Remove(entity); 53 } 54 55 public virtual void Delete(Expression<Func<T, bool>> where) 56 { 57 IEnumerable<T> objects = dbset.Where<T>(where).AsEnumerable(); 58 dbset.RemoveRange(objects); 59 } 60 61 //新增方法 62 public virtual void DeleteAll(IEnumerable<T> entities) 63 { 64 dbset.RemoveRange(entities); 65 } 66 67 public virtual void Clear() 68 { 69 throw new NotImplementedException(); 70 } 71 72 public virtual T GetById(long id) 73 { 74 return dbset.Find(id); 75 } 76 77 public virtual T GetById(string id) 78 { 79 return dbset.Find(id); 80 } 81 82 public virtual IEnumerable<T> GetAll() 83 { 84 return dbset.ToList(); 85 } 86 87 public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where) 88 { 89 return dbset.Where(where).ToList(); 90 } 91 92 public T Get(Expression<Func<T, bool>> where) 93 { 94 return dbset.Where(where).FirstOrDefault<T>(); 95 } 96 97 public virtual IEnumerable<T> GetAllLazy() 98 { 99 return dbset; 100 } 101 102 }
五、Repository
1 public interface IStuEducationRepo : IRepository<TB_Stu_Education> 2 { 3 4 }
1 public class StuEducationRepo : RepositoryBase<TB_Stu_Education>, IStuEducationRepo 2 { 3 public StuEducationRepo(IDatabaseFactory databaseFactory) 4 : base(databaseFactory) 5 { 6 7 } 8 9 }
六、工作单元
在进行数据库的CUD操作时,因为Repository内部没有做SaveChanges()操作
所以要增加工作单元,进行包裹
1 public interface IUnitOfWork 2 { 3 void Commit(); 4 void CommitAsync(); 5 }
1 public class UnitOfWork : IUnitOfWork 2 { 3 private readonly IDatabaseFactory databaseFactory; 4 private Db1DbContext dataContext; 5 6 public UnitOfWork(IDatabaseFactory databaseFactory) 7 { 8 this.databaseFactory = databaseFactory; 9 } 10 11 protected Db1DbContext DataContext 12 { 13 get { return dataContext ?? (dataContext = databaseFactory.Get()); } 14 } 15 16 public void Commit() 17 { 18 DataContext.SaveChanges(); 19 } 20 21 public void CommitAsync() 22 { 23 DataContext.SaveChangesAsync(); 24 } 25 26 }
七、Autofac注册
1 var builder = new ContainerBuilder(); 2 builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); 3 4 5 builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerLifetimeScope(); 6 builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope(); 7 8 builder.RegisterAssemblyTypes(typeof(StuEducationRepo).Assembly) 9 .Where(t => t.Name.EndsWith("Repo")) 10 .AsImplementedInterfaces().InstancePerLifetimeScope(); 11 12 builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration); 13 IContainer container = builder.Build(); 14 var resolver = new AutofacWebApiDependencyResolver(container); 15 16 // Configure Web API with the dependency resolver. 17 GlobalConfiguration.Configuration.DependencyResolver = resolver;
八、调用示例
1 // GET api/<controller>/5 2 public string Get(int id) 3 { 4 5 var stuAccount = _stuAccountRepo.Get(p => p.UserId == 20987); 6 if (stuAccount != null) 7 { 8 stuAccount.UserName = "张冬林Test"; 9 } 10 11 var stuEducation = _stuEducationRepo.GetMany(p => p.UserId == 20987); 12 if (stuEducation != null && stuEducation.Count() > 0) 13 { 14 foreach (var i in stuEducation) 15 { 16 i.ModifyDate = new DateTime(2016, 06, 14); 17 } 18 } 19 20 _unitOfWork.Commit(); 21 22 return "value"; 23 }
九、总结说明
1、Global Autofac注册,以保证在一次Http请求的生命周期内的DbContext是单例的
builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerLifetimeScope();
private Db1DbContext dataContext;public Db1DbContext Get(){return dataContext ?? (dataContext = new Db1DbContext()); }
这样Repository和UnitOfWork的DbContext 是一个对象,即同一个数据库上下文。所以 实现了 CRUD 与 数据持久化 两个步骤的分离
public virtual void Update(T entity){dbset.Attach(entity);dataContext.Entry(entity).State = EntityState.Modified;}
private readonly IDatabaseFactory databaseFactory;private Db1DbContext dataContext;public UnitOfWork(IDatabaseFactory databaseFactory) { this.databaseFactory = databaseFactory; } protected Db1DbContext DataContext { get { return dataContext ?? (dataContext = databaseFactory.Get()); } } public void Commit() { DataContext.SaveChanges(); }
2、Entity Framework本身就是一仓储,但DDD的这种设计并非画蛇添足。接口定义与代码实现的分离,可以不用关心ORM,可以不用关心是何种DB
附:源码下载
转载于:https://www.cnblogs.com/spilledlight/articles/9257186.html
DDD-EF-数据仓储相关推荐
- 从零开始,搭建博客系统MVC5+EF6搭建框架(1),EF Code frist、实现泛型数据仓储以及业务逻辑
前言 文章开始,我说过我要用我自学的技术,来搭建一个博客系统,也希望大家给点意见,另外我很感谢博客园的各位朋友们,对我那篇算是自我阶段总结文章的评论,在里面能看出有很多种声音,有支持的我的朋 ...
- EFCore的数据仓储模式
在EntityFramworkCore 配置种子数据中有降到如何配置种子数据,接下里就讲一讲数据仓储模式. 目录 1.动机 1.1 时下数据驱动应用是如何访问数据库 1.2Repository Des ...
- 数据仓储模式UnitOfWorks和Repository的实现
数据仓储模式UnitOfWorks和Repository的实现( 网上看了相关内容关于UnitOfWorks和Repository的数据仓储模式的实现,也来动手搭建下. ORM使用微软自己的EF来实现 ...
- 在数据仓储的情况下进一步封装数据库基础操作,此版本为异步版本
1 /// <summary> 2 /// 在数据仓储的情况下进一步封装数据库基础操作,此版本为异步版本 Created by ZhangQC 2016.08.17 3 /// </ ...
- 云计算是否为数据仓储做好了准备呢?
原文链接:http://blogs.sap.com/innovation/cloud-computing/is-cloud-ready-for-data-warehousing-022232<? ...
- Abp vNext 自定义 Ef Core 仓储引发异常
Abp vNext 自定义 Ef Core 仓储引发异常 参考文章: (1)Abp vNext 自定义 Ef Core 仓储引发异常 (2)https://www.cnblogs.com/myzony ...
- EF数据迁移命令总结
EF数据迁移命令总结 2018-09-29 22:41:30 一头小驴 阅读数 442 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链 ...
- 后台管理框架之五 :数据仓储设计
前面已经介绍了数据持久化部分的数据模型设计,现在我们来介绍数据操作部分的设计,也就是数据的增.删.改.查等CRUDQ操作的仓储设计.仓储设计主要依照以下几个思路: 一. 本项目数据操作 ...
- ef 数据迁移mysql_07116.3.0如何将CM的外部PostgreSQL数据库迁移至MySQL服务
文档编写目的 在前面的文章<6.3.0-如何将CM内嵌PostgreSQL服务迁移至外部PostgreSQL服务>介绍了将CM内嵌的PostgreSQL迁移至外部PostgreSQL,因为 ...
- ef 数据迁移mysql_EF6 Codefirst+MySql 数据库迁移
简介 项目使用MSSql作为数据库,但是因为SQL服务器贵那么一点,并发连接差那么一点,要把数据迁移到MySQL,顺带迁移过程以及问题. 环境 · Visual Studio 2013 · MySQL ...
最新文章
- 龟兔赛跑的升级版本和在课业学习上的应用
- Android自己定义组件系列【4】——自己定义ViewGroup实现双側滑动
- Linux Kconfig及Makefile学习
- c语言inline不起作用,C语言inline内联函数学习小结
- Java中注解学习系列教程-1
- android 5.0 ble demo,Android BLE蓝牙例子(包括android版Lightblue)实例源码
- 华师本科网络英语 计算机统考,2020华中师大计算机考研经验帖(已上岸)
- 引入tinymce-vue后调试器报错 Refused to apply styl
- CF 705A Hulk
- Zabbix安装错误解决方案
- Apache DolphinScheduler 社区呼唤志愿者
- 辽宁机电职业技术学院计算机专业在哪个校区,辽宁机电职业技术学院
- MySQL拷贝表结构、表数据总结
- 实现时间的计算: 要求用户输入身份证号,若格式有误,要求其重新输入。然后根据身份证号码输出20岁生日所在周的周三的日期
- vue前端导出excel,js-xlsx、xlsxStyle,可设置样式、表格合并;(包含获取excel列数函数、excel合并表格缺少边框处理函数)
- Java零基础学习Day01(搭配视频)
- 二极管专题:二极管的反向恢复时间(动态特性)
- 树莓派开发笔记(二)搭建智能家居系统(1) — Home Bridge + Home Assistant
- GC1262E/S 单线圈无刷直流电机驱动芯片 PWM调速 、斜率控制、软启动、自锁保护 可匹配APX9262S
- SQL Server【数据库-系统设计-大作业】【教学管理系统】【完整代码】