DDD-EF-数据仓储

本文介绍了一种使用Entity Framework实现仓储模式的方法,包括定义仓储接口、创建抽象基类、具体仓储实现及工作单元模式等关键部分,并提供了完整的示例代码。

转载来源 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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值