关于MVC EF架构及Repository模式的一点心得

   一直都想写博客,惋惜真的太懒了或者对本身的描述水平不太自信,因此。。。一直都是不想写的状态,关于领域驱动的东西看了很多,可是因为本身水平太差加上工做中实在用不到,因此一直处于搁置状态,最近心血来潮忽然想从新写一个本身的项目架构,因而开始了新一论的学习历程。数据库

   在设计以前我理了一下本身的大体需求也参考了不一样人的项目架构,在此特别感谢郭明峰的OSharp给个人启示,每一个人对架构的需求和使用习惯都是不一至的,在不一样大小的项目上使用的架构也不尽相同,如何取舍性能、开发速度及维护性的问题上每开发者都在本身心中有一杆秤,下面谈谈我理想中的架构,它应该提供一些经常使用的操做封装及各类工具方便实现多个功能,他应该包括数据操做的方便处理,他应该提供日志及缓存的处理功能,它的每种实现是本身换的但又得具备默认值让我在作私单的时候更快捷方便,基于以上特色因而总结了以下模块:缓存

1,工具库:提供了各类经常使用操做,如字符串截取,各类验证之类的helper类架构

2,核心库:提供缓存日志数据的接口及缓存日志的基础实现app

3,WEB库:针对网站相关的扩展及操做封装异步

4,MVC库:针对MVC网站的相关扩展及操做封装async

5,基础数据库模块实现库(如:EF)ide

回到每一个架构的重点:数据访问模块上来,如今比较流行使用EF+ IUnitOfWork+Repository来实现数据的处理,诚然这种方式让每个模块相互的依赖变得更小,更方便测试,更XXX,可是在个人实践中,仍是发现他真的麻烦,在我作一个中小项目的时候,添加一个普通的表不得不去添加实体,实体配置,仓储接口,仓储实现,服务接口,服务实现,controller viewmodel,view一系列下来即使是拷贝也是很是慢,即便咱们能够用代码生成器,我仍是以为太麻烦了。固然Repository模式的反对者也很多,做为一种数据操做的隔离手段,我我的以为Repository仍是颇有必要存在的,通过各类取舍,最后本身使用了一种折中的方式来使用Repository,个人方式是使用IStore来代替IUnitOfWork,本质是同样的,只是IStore实现的功能要多一些,同时使用了IStore使得咱们能够很容易的替换咱们的数据库功能实现,以下图:工具

因为通常的项目不须要一人写定义一人写实现,因此直接省去了IUserRepository及IUserService这种并不会修改实现的接口,固然若是有团队共同开发的时候使用也是彻底没有问题的,有了以上的图就开以开始实现代码了:性能

IDataStore:学习

 

 1 /// <summary>
 2     /// 数据存储器接口
 3     /// </summary>
 4     public interface IStore : IDisposable
 5     {
 6         #region UnitOfWork
 7         /// <summary>
 8         /// 获取或设置 是否开启事务提交
 9         /// </summary>
10         bool TransactionEnabled { get; set; }
11         /// <summary>
12         /// 提交操做
13         /// </summary>
14         bool Commit();
15         /// <summary>
16         /// 异步提交
17         /// </summary>
18         Task<bool> CommitAsync();
19         #endregion
20 
21         #region 基础操做
22         /// <summary>
23         /// 添加对像
24         /// </summary>
25         void Add<TEntity>(TEntity entity) where TEntity : class;
26         /// <summary>
27         /// 更新对像
28         /// </summary>
29         void Update<TEntity>(TEntity entity) where TEntity : class;
30         /// <summary>
31         /// 删除对像
32         /// </summary>
33         void Remove<TEntity>(TEntity entity) where TEntity : class; 
34         #endregion
35 
36         #region 查询操做
37         /// <summary>
38         /// 获取数据集查询对像
39         /// </summary>
40         IQueryable<TEntity> GetQueryEntities<TEntity, TKey>() where TEntity : class;
41         #endregion
42     }

IRepository:

/// <summary>
    /// 仓储接口
    /// </summary>
    /// <typeparam name="TEntity">实体类型</typeparam>
    /// <typeparam name="TKey">实体主键类型</typeparam>
    public interface IRepository<TEntity, TKey> 
    {
        #region 属性
        /// <summary>
        /// 获取当前数据存储器
        /// </summary>
        IStore DataStore { get; }
        /// <summary>
        /// 获取当前实体的查询数据集
        /// </summary>
        IQueryable<TEntity> Entities { get; }
        #endregion

        #region 基础操做
        /// <summary>
        /// 添加实体到仓库
        /// </summary>
        void Add(TEntity entity);
        /// <summary>
        /// 更新仓库中的实体
        /// </summary>
        void Update(TEntity entity);
        /// <summary>
        /// 从仓库删除指定key的实体
        /// </summary>
        void Remove(TEntity entity);        
        #endregion

        #region 查询
        /// <summary>
        /// 获取指定key的实体
        /// </summary>
        TEntity FindByKey(TKey key);
        #endregion
    }

RepositroyBase:

 1 /// <summary>
 2     /// 仓储基类
 3     /// </summary>
 4     public abstract class RepositoryBase<TEntity, TKey> : IRepository<TEntity, TKey>
 5         where TEntity : EntityBase<TKey>, new()
 6     {
 7 
 8         public IStore DataStore { get; set; }
 9 
10         public IQueryable<TEntity> Entities
11         {
12             get { return this.DataStore.GetQueryEntities<TEntity, TKey>(); }
13         }
14 
15         public void Add(TEntity entity)
16         {
17             this.DataStore.Add<TEntity>(entity);
18         }
19 
20         public void Update(TEntity entity)
21         {
22             this.DataStore.Update<TEntity>(entity);
23         }
24 
25         public void Remove(TEntity entity)
26         {
27             this.DataStore.Remove<TEntity>(entity);
28         }
29 
30         public TEntity FindByKey(TKey key)
31         {
32             return this.Entities.Where(t => t.Id.Equals(key)).SingleOrDefault();
33         }
34     }

固然BaseEntity这种东西就看本身爱好添加了,按key删除,按条件更新的方法这里就不写了

,另外关于返回Repository返回IEnumerable仍是IQueryable这个问题我我的认为若是不按照DDD的的标准来看,一个仓库每次拿你想要的东西仍是给你一个通道你想拿多少就拿多少本质上都是能够的,不过对于隔离开发人员直接操做数据确实存在隐患,不过谁叫他简单呢?看完定义,而后若是要使用EF作为ORM来操做数据库或者任意继承至IDataStore的库来完成数据操做,不过这里要本身写的话,解析表达式仍是有点困难的。。贴下简单EF基类的简单实现:

 

 1 /// <summary>
 2     /// EF数据存储器(抽象类)
 3     /// </summary>
 4     public abstract class EFDataStore : DbContext, IStore
 5     {
 6         #region DbContext
 7         protected EFDataStore() { }
 8         protected EFDataStore(DbCompiledModel model) : base(model) { }
 9         public EFDataStore(string nameOrConnectionString) : base(nameOrConnectionString) { }
10         public EFDataStore(DbConnection existingConnection, bool contextOwnsConnection) : base(existingConnection, contextOwnsConnection) { }
11         public EFDataStore(ObjectContext objectContext, bool dbContextOwnsObjectContext) : base(objectContext, dbContextOwnsObjectContext) { }
12         public EFDataStore(string nameOrConnectionString, DbCompiledModel model) : base(nameOrConnectionString, model) { }
13         public EFDataStore(DbConnection existingConnection, DbCompiledModel model, bool contextOwnsConnection) : base(existingConnection, model, contextOwnsConnection) { }
14         /// <summary>
15         /// 实体映射集合
16         /// </summary>
17         public IEnumerable<IEntityMapper> EntityConfigurations { get; set; }
18 
19         protected override void OnModelCreating(DbModelBuilder modelBuilder)
20         {
21             //foreach (var mapper in EntityConfigurations)
22             //{
23             //    mapper.RegistTo(modelBuilder.Configurations);
24             //}
25         }
26         #endregion
27 
28         public bool TransactionEnabled { get; set; }
29 
30         public IQueryable<TEntity> GetQueryEntities<TEntity, TKey>() where TEntity : class
31         {
32             return this.Set<TEntity>();
33         }
34 
35         public bool Commit()
36         {
37             var r = this.SaveChanges();
38             //this.Dispose();
39             return r > 0;
40         }
41 
42         public async Task<bool> CommitAsync()
43         {
44             return (await this.SaveChangesAsync()) > 0;
45         }
46 
47         public void Add<TEntity>(TEntity entity) where TEntity : class
48         {
49             this.Set<TEntity>().Add(entity);
50         }
51 
52         public void Update<TEntity>(TEntity entity) where TEntity : class
53         {
54             this.Entry(entity).State = EntityState.Modified;
55         }
56 
57         public void Remove<TEntity>(TEntity entity) where TEntity : class
58         {
59             this.Entry(entity).State = EntityState.Deleted;
60         }
61     }

这。写着写着本身都有点不知所云了,但愿对正在学习阶段的朋友有一点点帮助!

相关文章
相关标签/搜索