接着上篇文章扩展ASP.NET MVC三层框架并使用StructureMap实现依赖注入1-Model层的实现,这篇文章主要介绍一下和Model层打交道的Repository数据库持久层。之所以建立Repository这一层是为了防止Service业务逻辑层直接和Model数据库层打交道,这样将来如果我们的系统数据库由于各种原因更换,这时我们只需要修改Repository层和Model层,对于Service层我们是不需要修改的。
这时你会想我在Service层调用了Repository层的代码,为什么不需要修改Service层?这要得益于我们使用的StructureMap这个依赖注入框架,不同层之间,我们的在代码中是不会自己去new创建其它层的对象的,创建实例的事情统统交给StructureMap去做,通过接口调用不同层的方法,你会发现本系统使用了非常神秘的面向接口编程~ 嘿嘿。 StructureMap的配置和使用,这篇文章不作介绍,等我们完成了Repository和service工程,再加上一个Interface工程之后,我们再去实现StructureMap。因为将来会使用StructureMap所以Interface工程将会和Repository工程一起介绍。
首先是TYStudioDemo.Repositories和TYStudioDemo.Interfaces两个工程的截图
为了方便维护所有的接口都放在TYStudioDemo.Interfaces工程里面,由于本系统只是一个Demo,所以只对数据库中Supplier这个表进行简单的曾删改查操作,起到抛砖引玉的作用,接下来俺要开始扔砖了~
由于增删改查是每个表都有的操作,所以这里抽取出来一个Repository的顶级接口ITYRepository,我们使用泛型来约束处理的Entity。这里面定义了一些基础的linq操作方法,相信使用过Linq和EntityFramework的人一眼就能看出这里声明的方法的作用,so不在一一说明(不明白的百度一下,你就知道)。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace TYStudioDemo.Interfaces 8 { 9 public interface ITYRepository<T> where T : class 10 { 11 IQueryable<T> Fetch(); 12 IEnumerable<T> GetAll(); 13 IEnumerable<T> Find(Func<T, bool> predicate); 14 T Single(Func<T, bool> predicate); 15 T SingleOrDefault(Func<T, bool> predicate); 16 T First(Func<T, bool> predicate); 17 void Create(T entity); 18 void Delete(T entity); 19 void Delete(Func<T, bool> predicate); 20 void Attach(T entity); 21 } 22 }
接下来是接口ITYRepository的实现类TYRepository,实现顶级接口中的每个方法。在这里我们就用到了上篇文章定义的TYEntities.Current了,保证了多个Repository的线程安全和事务处理。实际使用时,有时你需要多个Entity的Repository,我们可以一个一个的操作,但是我们只调用一次TYEntities.Current.SaveChanges()方法,着所有的操作都在一个datacontext里面了,保证了事务处理。具体的使用方法,将在Service篇介绍给大家。下面是TYRepository的代码实现:
1 using System; 2 using System.Collections.Generic; 3 using System.Data.Objects; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using TYStudioDemo.Interfaces; 8 using TYStudioDemo.Models; 9 10 namespace TYStudioDemo.Repositories 11 { 12 public class TYRepository<T> : ITYRepository<T> where T : class 13 { 14 protected ObjectContext _context; 15 16 private IObjectSet<T> _objectSet; 17 18 public TYRepository() 19 { 20 //总是返回当前的datacontext,详细说明请看教程的Models篇 21 _context = TYEntities.Current; 22 _objectSet = _context.CreateObjectSet<T>(); 23 } 24 25 public IQueryable<T> Fetch() 26 { 27 return _objectSet.AsQueryable<T>(); 28 } 29 30 public IEnumerable<T> GetAll() 31 { 32 return Fetch().AsEnumerable<T>(); 33 } 34 35 public IEnumerable<T> Find(Func<T, bool> predicate) 36 { 37 return _objectSet.Where<T>(predicate); 38 } 39 40 public T Single(Func<T, bool> predicate) 41 { 42 return _objectSet.Single<T>(predicate); 43 } 44 45 public T SingleOrDefault(Func<T, bool> predicate) 46 { 47 return _objectSet.SingleOrDefault<T>(predicate); 48 } 49 50 public T First(Func<T, bool> predicate) 51 { 52 return _objectSet.First<T>(predicate); 53 } 54 55 public void Delete(T entity) 56 { 57 if (entity == null) 58 { 59 throw new ArgumentNullException("entity"); 60 } 61 62 _objectSet.DeleteObject(entity); 63 } 64 65 public void Delete(Func<T, bool> predicate) 66 { 67 IEnumerable<T> records = from x in _objectSet.Where<T>(predicate) select x; 68 69 foreach (T record in records) 70 { 71 _objectSet.DeleteObject(record); 72 } 73 } 74 75 public void Create(T entity) 76 { 77 if (entity == null) 78 { 79 throw new ArgumentNullException("entity"); 80 } 81 _objectSet.AddObject(entity); 82 } 83 84 public void Attach(T entity) 85 { 86 _objectSet.Attach(entity); 87 } 88 } 89 }
现在我们有了顶级的ITYRepository接口和它的实现类TYRepository,接下来就可以实现个体Entity的repository了。
首先我们建立一个ISupplierRepository接口,为什么要建立这个接口呢,因为我们是面向接口编程,将来需要用StructureMap实现将它的实现类SupplierRepository注入到Service层,并且这里可以声明除了ITYRepository中方法以外的方法,也就是对ITYRepository一个扩展,属于SupplierRepository自己的方法,这里我们简单的声明一个GetByCompanyName(string companyName)方法,在实际使用中,如果需要自己的处理操作,就将方法声明在这里,而不是ITYRepository,如果不需要可以不声明任何方法,但是这个接口是一定要有的。我们需要注入到Service的。 下面是ISupplierRepository代码:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace TYStudioDemo.Interfaces 8 { 9 public interface ISupplierRepository<T> : ITYRepository<T> where T : class 10 { 11 //声明一个通过companyName获得supplier的方法 12 //注意这个方法是ITYRepository没有声明的,也就是我们扩展的业务方法。 13 T GetByCompanyName(string companyName); 14 } 15 }
接下来是ISupplierRepository的实现类SupplierRepository,这里需要注意的是,SupplierRepository同时需要继承顶级接口ITYRepository的实现类TYRepository,这样ITYRepository声明的公共方法就不需要在SupplierRepository里实现了,因为我们已经在TYRepository实现了。所以这只需要实现ISupplierRepository声明的方法GetByCompanyName(string companyName)
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using TYStudioDemo.Interfaces; 7 using TYStudioDemo.Models; 8 9 namespace TYStudioDemo.Repositories 10 { 11 public class SupplierRepository : TYRepository<Supplier>, ISupplierRepository<Supplier> 12 { 13 //实现ISupplierRepository中的方法 14 15 #region ISupplierRepository<Supplier> Members 16 17 public Supplier GetByCompanyName(string companyName) 18 { 19 return TYEntities.Current.Suppliers.SingleOrDefault(e=>e.CompanyName == companyName); 20 } 21 22 #endregion 23 } 24 }
到这里SupplierRepository全部实现了。
总结:至此Repository数据库持久层就介绍完了。Repository层主要搞清楚顶级接口ITYRepository以及它的实现类TYRepository和ISupplierRepository以及实现类SupplierRepository之间的继承关系,如果不明白补一补面向对象的基础吧。
下篇文章将介绍Service业务逻辑层的实现。
天屹一定抽出时间会尽快更新完成这一系列的文章,全部文章结束之后天屹会公开分享系统的代码供大家下载。
如果觉得文章内容还行,请点一下推荐,让更多的人看见,天屹会有更多的动力写下去,并且完善系统。原创文章转载请注明出处,谢谢。
相关文章
<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>