关系图

一、分层

二、DomainObjects构建edmx

三、EFRepositoryDemo.Domain定义仓储接口

 public interface IRepository<T>
where T : class
{
void Add(T entity);
void AddAll(IEnumerable<T> entities);
void Update(T entity);
void Update(IEnumerable<T> entities);
void Delete(T entity);
void Delete(Expression<Func<T, bool>> where);
void DeleteAll(IEnumerable<T> entities); void Clear();
T GetById(long Id);
T GetById(string Id);
T Get(Expression<Func<T, bool>> where);
IEnumerable<T> GetAll();
IEnumerable<T> GetMany(Expression<Func<T, bool>> where);
IEnumerable<T> GetAllLazy();
}

四、Infrastructure层 仓储的抽象基类(EF的CRUD)

Repository很明显的一个特征 是 内部没有SaveChanges()

 public abstract class EFRepositoryBase<T> where T : class
{
private Db1DbContext dataContext;
private readonly DbSet<T> dbset; protected IDatabaseFactory DatabaseFactory
{
get;
private set;
} protected Db1DbContext DataContext
{
get { return dataContext ?? (dataContext = DatabaseFactory.Get()); }
} protected EFRepositoryBase(IDatabaseFactory databaseFactory)
{
DatabaseFactory = databaseFactory;
dbset = DataContext.Set<T>();
} public virtual void Add(T entity)
{
dbset.Add(entity);
} //新增方法
public virtual void AddAll(IEnumerable<T> entities)
{
dbset.AddRange(entities);
} public virtual void Update(T entity)
{
dbset.Attach(entity);
dataContext.Entry(entity).State = EntityState.Modified;
} //新增方法
public virtual void Update(IEnumerable<T> entities)
{
foreach (T obj in entities)
{
dbset.Attach(obj);
dataContext.Entry(obj).State = EntityState.Modified;
}
} public virtual void Delete(T entity)
{
dbset.Remove(entity);
} public virtual void Delete(Expression<Func<T, bool>> where)
{
IEnumerable<T> objects = dbset.Where<T>(where).AsEnumerable();
dbset.RemoveRange(objects);
} //新增方法
public virtual void DeleteAll(IEnumerable<T> entities)
{
dbset.RemoveRange(entities);
} public virtual void Clear()
{
throw new NotImplementedException();
} public virtual T GetById(long id)
{
return dbset.Find(id);
} public virtual T GetById(string id)
{
return dbset.Find(id);
} public virtual IEnumerable<T> GetAll()
{
return dbset.ToList();
} public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
{
return dbset.Where(where).ToList();
} public T Get(Expression<Func<T, bool>> where)
{
return dbset.Where(where).FirstOrDefault<T>();
} public virtual IEnumerable<T> GetAllLazy()
{
return dbset;
} }

五、Repository 

     public interface IStuEducationRepo : IRepository<TB_Stu_Education>
{ }
     public class StuEducationRepo : RepositoryBase<TB_Stu_Education>, IStuEducationRepo
{
public StuEducationRepo(IDatabaseFactory databaseFactory)
: base(databaseFactory)
{ } }

六、工作单元

在进行数据库的CUD操作时,因为Repository内部没有做SaveChanges()操作

所以要增加工作单元,进行包裹

     public interface IUnitOfWork
{
void Commit();
void CommitAsync();
}
 public class UnitOfWork : IUnitOfWork
{
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();
} public void CommitAsync()
{
DataContext.SaveChangesAsync();
} }

七、Autofac注册

             var builder = new ContainerBuilder();
builder.RegisterApiControllers(Assembly.GetExecutingAssembly()); builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerLifetimeScope();
builder.RegisterType<UnitOfWork>().As<IUnitOfWork>().InstancePerLifetimeScope(); builder.RegisterAssemblyTypes(typeof(StuEducationRepo).Assembly)
.Where(t => t.Name.EndsWith("Repo"))
.AsImplementedInterfaces().InstancePerLifetimeScope(); builder.RegisterWebApiFilterProvider(GlobalConfiguration.Configuration);
IContainer container = builder.Build();
var resolver = new AutofacWebApiDependencyResolver(container); // Configure Web API with the dependency resolver.
GlobalConfiguration.Configuration.DependencyResolver = resolver;

八、调用示例

 // GET api/<controller>/5
public string Get(int id)
{ var stuAccount = _stuAccountRepo.Get(p => p.UserId == );
if (stuAccount != null)
{
stuAccount.UserName = "张冬林Test";
} var stuEducation = _stuEducationRepo.GetMany(p => p.UserId == );
if (stuEducation != null && stuEducation.Count() > )
{
foreach (var i in stuEducation)
{
i.ModifyDate = new DateTime(, , );
}
} _unitOfWork.Commit(); return "value";
}

九、总结说明

  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

  附:源码下载

DDD-EF-数据仓储的更多相关文章

  1. 从零开始,搭建博客系统MVC5+EF6搭建框架(1),EF Code frist、实现泛型数据仓储以及业务逻辑

    前言      从上篇30岁找份程序员的工作(伪程序员的独白),文章开始,我说过我要用我自学的技术,来搭建一个博客系统,也希望大家给点意见,另外我很感谢博客园的各位朋友们,对我那篇算是自我阶段总结文章 ...

  2. 9.10 翻译系列:EF数据注解特性之StringLength【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/stringlength-dataannotations-attribute-in-co ...

  3. 9.7 翻译系列:EF数据注解特性之--InverseProperty【EF 6 Code-First系列】

    原文链接:https://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in ...

  4. EF 数据查询效率对比

    优化的地方: 原地址:https://www.cnblogs.com/yaopengfei/p/9226328.html ①:如果仅是查询数据,并不对数据进行增.删.改操作,查询数据的时候可以取消状态 ...

  5. C#数据仓储类

    https://ninesky.codeplex.com/SourceControl/latest /*============================== 版本:v0.1 创建:2016.2 ...

  6. .netCoreMVC添加数据仓储

    在上一篇关于CodeFirst从零搭建ASP.NETCore2.0中搭建起了完整.netCoreMVC项目,在这一篇中将实现如何注册service服务和Repository数据仓储到web中实现数据的 ...

  7. Abp vNext 自定义 Ef Core 仓储引发异常

    问题 在使用自定义 Ef Core 仓储和 ABP vNext 注入的默认仓储时,通过两个 Repository 进行 Join 操作,提示 Cannot use multiple DbContext ...

  8. DDD与数据事务脚本

    DDD与数据事务脚本 扯淡 相信点进来看这篇文章的同学,大部分是因为标题里面的"DDD"所吸引!DDD并不是一个新技术,如果你百度一下它的历史就会知道,实际上它诞生于2004年, ...

  9. 【干货】利用MVC5+EF6搭建博客系统(一)EF Code frist、实现泛型数据仓储以及业务逻辑

    习MVC有一段时间了,决定自己写一套Demo了,写完源码再共享. PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.框架搭建 二.创建数据库 1.创建一个空的EF code fr ...

  10. 用MVC5+EF6+WebApi 做一个考试功能(六) 仓储模式 打造EF通用仓储类

    前言 年底工作比较忙,年度总结还没写,项目要上线,回老家过年各种准备.尤其是给长辈给侄子侄女准备礼物头都大了. 原来想年前先出一版能用的,我看有点悬了,尽量先把大体功能弄出来,扔掉一些,保证能考试,然 ...

随机推荐

  1. Hexo+GitHub+Netlify一站式搭建属于自己的博客网站

    喜欢的话请关注我的个人博客我在马路边https://hhongwen.cn/,此文为博主原创,转载请标明出处. 更好的阅读体验请点击查看:Hexo+GitHub+Netlify一站式搭建属于自己的博客 ...

  2. hadoop、storm和spark的区别、比较

    一.hadoop.Storm该选哪一个? 为了区别hadoop和Storm,该部分将回答如下问题:1.hadoop.Storm各是什么运算2.Storm为什么被称之为流式计算系统3.hadoop适合什 ...

  3. scrapy爬取验证码登录网页

    scrapy 验证码登录程序, https://accounts.douban.com/login # -*- coding: utf-8 -*- import scrapy import urlli ...

  4. [Reship] Mean Shift 算法介绍

    ==================================================================================== This article ca ...

  5. test20181029 思考熊的马拉松

    题意 思考熊的马拉松 问题描述 今年,n只思考熊参加了校园马拉松比赛.马拉松的赛道是环形的,每圈的长度是A,完成比赛需要跑L圈. 比赛中,甲领先乙很长距离,绕过一圈或多圈后从后面追上了乙的现象叫做&q ...

  6. .NET平台上的Model-View-Presenter模式实践

    为什么要写这篇文章 笔者当前正在负责研究所中一个项目,这个项目基于.NET平台,初步拟采用C/S部署体系,所以选择了Windows Forms作为其UI.经过几此迭代,我们发现了一个问题:虽然业务逻辑 ...

  7. Ubuntu上kubeadm安装Kubernetes集群

    一 创建VM 3台VM,其中一台为master节点,2台work node: 二 安装相关软件 在所有节点上运行: apt-get update apt-get install apt-transpo ...

  8. laravel的blade模板的布局嵌套

    测试路由 Route::get('/', function() { $value = [,,]; return view('home.index', array('data' => $value ...

  9. 多分类下的ROC曲线和AUC

    本文主要介绍一下多分类下的ROC曲线绘制和AUC计算,并以鸢尾花数据为例,简单用python进行一下说明.如果对ROC和AUC二分类下的概念不是很了解,可以先参考下这篇文章:http://blog.c ...

  10. docker监控的一点想法

    目前项目内部署了docker,于是涉及到关于监控的事情,参考一些经典实例以及一些自己的想法,总结一下思路. 1.关于监控的内容 监控宿主机本身 监控宿主机本身还是比较简单的,同其他服务器监控类似,对c ...