关系图

一、分层

二、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. 用firefox获取html页面元素的Xpath

    Xpath在分析网页尤其是采集固定格式数据时,非常有用,且比正则表达式和首尾截取式更加简便.准确! 工具/原料   FireFox FireBug XpathChecker UserAgentSwit ...

  2. MySQL 字段基本操作

    MySQL添加字段的方法并不复杂,下面将为您详细介绍MySQL添加字段和修改字段等操作的实现方法,希望对您学习MySQL添加字段方面会有所帮助. .登录数据库 >mysql -u root -p ...

  3. 《DSP using MATLAB》示例Example 8.16

    %% ------------------------------------------------------------------------ %% Output Info about thi ...

  4. redis在mac中的安装和启动

    http://blog.csdn.net/chenshuai1993/article/details/51519384 http://www.jianshu.com/p/6b5eca8d908b

  5. 安装xamp之后,appach、mysql等问题的总结

    问题一:无法启动的问题 如果他们无法启动,大多数情况是端口号被占用. 首先就是查看端口号:点击“netstart“按钮查看端口号的使用详情 如果被占用就点击"config”按钮,进行端口号的 ...

  6. NumPy-快速处理数据--矩阵运算

    本文摘自<用Python做科学计算>,版权归原作者所有. 1. NumPy-快速处理数据--ndarray对象--数组的创建和存取 2. NumPy-快速处理数据--ndarray对象-- ...

  7. CentOS部署NetCore - 3. 部署站点

    一. CentOS 安装FTP linux 安装 ftp第一步 使用如下命令#rpm -qa |grep vsftpd可以检测出是否安装了vsftpd软件, 如果没有安装,使用YUM命令进行安装. y ...

  8. SQL中利用脚本恢复数据库

    SQL中利用脚本恢复数据库   编写人:CC阿爸 2014-6-15 在日常SQL数据库的操作中,如何恢复数据库 use master drop database SCS1 RESTORE DATAB ...

  9. c#通过app.manifest使程序 右键 以管理员身份运行

    c#通过app.manifest使程序以管理员身份运行 时间:2013-06-27 22:47来源:网络收集+本站整理 作者:jtydl 点击: 1175 次 微软在Windows Vista开始引入 ...

  10. Java 方法签名

    方法签名格式: 方法名   参数列表 例如: public class A{ protected int method (int a, int b) { return 0; } } class B e ...