DDD-EF-data warehousing, ddd-ef-warehousing
Relationship Diagram
I. layering
2. Build edmx using DomainObjects
3. EFRepositoryDemo. Domain defines the warehousing Interface
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 }
Iv. abstract base class (ef crud) of Infrastructure layer warehousing)
One obvious feature of Repository is that there is no SaveChanges () internally ()
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 // Add method 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 // Add Method 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 // Add method 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> getsums (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}
V. Repository
1 public interface IStuEducationRepo : IRepository<TB_Stu_Education>2 {3 4 }
1 public class StuEducationRepo : RepositoryBase<TB_Stu_Education>, IStuEducationRepo2 {3 public StuEducationRepo(IDatabaseFactory databaseFactory)4 : base(databaseFactory)5 {6 7 }8 9 }
Vi. Work Unit
The SaveChanges () operation is not performed in the Repository during CUD operations on the database.
So we need to add work units and package them.
1 public interface IUnitOfWork2 {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 DataContext12 {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 }
VII. Autofac Registration
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;
8. Call example
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 = "Zhang Donglin Test"; 9} 10 11 var stuEducation = _ stuEducationRepo. getparts (p => p. user ID = 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}
IX. Summary
1. Register Global Autofac to ensure that DbContext within the lifecycle of an Http request is a singleton
builder.RegisterType<DatabaseFactory>().As<IDatabaseFactory>().InstancePerLifetimeScope();
private Db1DbContext dataContext; public Db1DbContext Get() { return dataContext ?? (dataContext = new Db1DbContext()); }
In this way, the DbContext of Repository and UnitOfWork is an object, that is, the same database context. Therefore, the separation of CRUD and data persistence is realized.
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 itself is a warehouse, but this design of DDD is not superfluous. Interface Definition and code implementation separation, you don't have to worry about ORM, you don't have to worry about what kind of DB
Attachment: source code download