程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> DDD-EF-數據倉儲,ddd-ef-倉儲

DDD-EF-數據倉儲,ddd-ef-倉儲

編輯:C#入門知識

DDD-EF-數據倉儲,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

 

  附:源碼下載

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved