• DDD-EF-数据仓储


      关系图

         

    一、分层

    二、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

      附:源码下载

  • 相关阅读:
    优秀的云架构师需要学什么技能
    dkh人力资源大数据解决方案整体架构
    大数据hadoop与spark的区别
    hadoop技术入门学习之发行版选择
    大数据开发基础知识需要掌握哪些
    智慧人社政务云平台建设方案架构案例介绍
    [项目机会]citrix 虚拟桌面对于java等高CPU占用率如何解决
    [办公自动化]无法使用江南天安usbkey 无法使用视频网站
    [学习笔记]从0到1
    [办公自动化]目录修改以及插入分页符后行间距自动变宽
  • 原文地址:https://www.cnblogs.com/frozenzhang/p/5390551.html
Copyright © 2020-2023  润新知