基于Repository模式设计项目架构—你可以参考的项目架构设计

关于Repository模式,直接百度查就可以了,其来源是《企业应用架构模式》。
我们新建一个Infrastructure文件夹,这里就是基础设施部分,EF Core的上下文类以及Repository层都放在这里面。
新建一个IReposotory的接口,其内容就是封装了基本的CRUD:

public interface IRepository<TEntity> where TEntity : class
 {
    ///获取当前实体的查询数据集
    IQueryable<TEntity> Entities{get;} 

    ///获取当前实体的数据集
    DbSet<TEntity> DbEntities{get;} 

 /// <summary>
 /// Gets all objects from database
 /// </summary>
 /// <returns></returns>
 IQueryable<TEntity> All(); 

 /// <summary>
 /// Gets objects from database by filter.
 /// </summary>
 /// <param name="predicate">Specified a filter</param>
 /// <returns></returns>
 IQueryable<TEntity> Filter(Expression<Func<TEntity, bool>> predicate); 

 /// <summary>
 /// Gets objects from database with filting and paging.
 /// </summary>
 /// <param name="filter">Specified a filter</param>
 /// <param name="total">Returns the total records count of the filter.</param>
 /// <param name="index">Specified the page index.</param>
 /// <param name="size">Specified the page size</param>
 /// <returns></returns>
 IQueryable<TEntity> Filter(Expression<Func<TEntity, bool>> filter, out int total, int index = 0, int size = 50); 

 /// <summary>
 /// Gets the object(s) is exists in database by specified filter.
 /// </summary>
 /// <param name="predicate">Specified the filter expression</param>
 /// <returns></returns>
 bool Contains(Expression<Func<TEntity, bool>> predicate); 

 /// <summary>
 /// Find object by keys.
 /// </summary>
 /// <param name="keys">Specified the search keys.</param>
 /// <returns></returns>
 TEntity Find(params object[] keys); 

 /// <summary>
 /// Find object by specified expression.
 /// </summary>
 /// <param name="predicate"></param>
 /// <returns></returns>
 TEntity Find(Expression<Func<TEntity, bool>> predicate); 

 /// <summary>
 /// Create a new object to database.
 /// </summary>
 /// <param name="t">Specified a new object to create.</param>
 /// <returns></returns>
 int Create(TEntity t); 

 /// <summary>
 /// Delete the object from database.
 /// </summary>
 /// <param name="t">Specified a existing object to delete.</param>
 void Delete(TEntity t); 

 /// <summary>
 /// Delete objects from database by specified filter expression.
 /// </summary>
 /// <param name="predicate"></param>
 /// <returns></returns>
 int Delete(Expression<Func<TEntity, bool>> predicate); 

 /// <summary>
 /// Update object changes and save to database.
 /// </summary>
 /// <param name="t">Specified the object to save.</param>
 /// <returns></returns>
 int Update(TEntity t); 

 /// <summary>
 /// Select Single Item by specified expression.
 /// </summary>
 /// <typeparam name="T"></typeparam>
 /// <param name="expression"></param>
 /// <returns></returns>
 TEntity FirstOrDefault(Expression<Func<TEntity, bool>> expression);
 }

创建一个基类,用来实现IRepository接口,同时作其余的Repository的基类

public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
 {
 protected readonly DbContext Context; 

 public BaseRepository(DbContext context)
 {
 Context = context;
 } 

/// 获取当前实体的查询数据集
public IQueryable<TEntity> Entities
{
get { return Context.Set<TEntity>().AsQueryable(); }
} 

/// 获取当前实体
public IQueryable<TEntity> Entities
{
get { return Context.Set<TEntity>(); }
} 

 public TEntity FirstOrDefault(Expression<Func<TEntity, bool>> expression)
 {
 return All().FirstOrDefault(expression);
 } 

 public IQueryable<TEntity> All()
 {
 return Context.Set<TEntity>().AsQueryable();
 } 

 public virtual IQueryable<TEntity> Filter(Expression<Func<TEntity, bool>> predicate)
 {
 return Context.Set<TEntity>().Where<TEntity>(predicate).AsQueryable<TEntity>();
 } 

 public virtual IQueryable<TEntity> Filter(Expression<Func<TEntity, bool>> filter, out int total, int index = 0,
 int size = 50)
 {
 var skipCount = index * size;
 var resetSet = filter != null
 ? Context.Set<TEntity>().Where<TEntity>(filter).AsQueryable()
 : Context.Set<TEntity>().AsQueryable();
 resetSet = skipCount == 0 ? resetSet.Take(size) : resetSet.Skip(skipCount).Take(size);
 total = resetSet.Count();
 return resetSet.AsQueryable();
 } 

 public virtual int Create(TEntity TObject)
 {
 Entities.Add(TObject);
 Context.SaveChanges();
 } 

 public virtual int Delete(TEntity TObject)
 {
 Entities.Remove(TObject);.
 Context.SaveChanges();
 } 

 public virtual void Update(TEntity TObject)
 {
 try
 {
 var entry = Context.Entry(TObject);
 Context.Set<TEntity>().Attach(TObject);
 entry.State = EntityState.Modified;
 }
 catch (OptimisticConcurrencyException ex)
 {
 throw ex;
 }
 } 

 public virtual int Delete(Expression<Func<TEntity, bool>> predicate)
 {
 var objects = Filter(predicate);
 foreach (var obj in objects)
 Context.Set<TEntity>().Remove(obj);
 return Context.SaveChanges();
 } 

 public bool Contains(Expression<Func<TEntity, bool>> predicate)
 {
 return Context.Set<TEntity>().Any(predicate);
 } 

 public virtual TEntity Find(params object[] keys)
 {
 return Context.Set<TEntity>().Find(keys);
 } 

 public virtual TEntity Find(Expression<Func<TEntity, bool>> predicate)
 {
 return Context.Set<TEntity>().FirstOrDefault<TEntity>(predicate);
 }
 }

新建一个实体类的接口:

public interface IStudentRepository : IRepository<Student>
 {
 int AddStudent(Student student);
 }

然后我们创建一个实体类的Repository:

public class StudentRepository : BaseRepository<Student>, IStudentRepository
 {
 private readonly SchoolContext _context; 

 public StudentRepository(SchoolContext context)
 : base(context)
 {
 _context = context;
 } 

int AddStudent(Student student)
{
_context.Create(student);
}
 }

在这里就已经做好了我们要做的了。接下来的就是注入依赖、在控制器里面的使用了。

我们完全可以自己来定制自己的Repository模式下的项目。其实整个的架构没有什么,我们只是将所有的CRUD操作封装到了IRepository接口里面,然后在BaseRepository中实现了一遍,而且如果你细心的话,你会发现IRepository里面的CRUD操作都是基于已有的扩展方法里面的,就是linq扩展方法的Add等源码,同时我们在BaseRepository类中,提供了DbSet<TEntity>属性以及查询数据集IQueryable<DbSet<TEntity>>,这也是有必要的,可以省却我们很多不必要的代码,因为我们所有的CRUD都是基于这两个的。然后我们基于BaseRepository来实现实体类的Repository,同时继承按需增加的IEntityRepository接口。但是在这里要注意,我们将DbContext的子类都放在了Infrastructure文件夹里面,是因为,一般我们继承自DbContext的子类都是操作数据库的中间类,属于基础设施一块,所以将其放在Infrastructure文件夹比较合适。

参考资料:
MVC实用架构设计(三)——EF-Code First(1):Repository,UnitOfWork,DbContext

分享基于Entity Framework的Repository模式设计(附源码)

《ASP.NET MVC框架揭秘》源码中的示例项目源码 S1402

原文地址:https://www.cnblogs.com/zhiyong-ITNote/p/9297405.html

时间: 2024-10-13 14:52:44

基于Repository模式设计项目架构—你可以参考的项目架构设计的相关文章

Servlet+oracle MVC 架构 搭建简易购物车web项目---数据库设计

Servlet+oracle MVC 架构 搭建简易购物车web项目 主要实现以下功能: 1.用户登录,从数据库验证用户的合法性. 2.购物大厅,从数据库取出商品进行展示. 3.在购物大厅可以点击购买商品,跳到我的购物车界面. 4.在我的购物车页面,可以更新商品数量,并能够计算商品总价.可以删除商品.可以提交订单. 5.提交订单以后,进入订单页面,展示个人信息和订单信息  6.再次提交订单以后,给用户发送电子邮件,提醒用户. 数据库设计 用户表 create table users ( id n

基于ASP.NET WPF技术及MVP模式实战太平人寿客户管理项目开发(Repository模式)

亲爱的网友,我这里有套课程想和大家分享,如果对这个课程有兴趣的,可以加我的QQ2059055336和我联系. 课程背景 本课程是教授使用WPF.ADO.NET.MVVM技术来实现太平人寿保险有限公司保险客户管理系统,是学习WPF开发中的一门主打课程之一. WPF是一个框架,它供程序员开发出媲美Mac程序的酷炫界面. Blend是一种工具,可以在美工板上绘制形状.路径和控件,然后修改其外观和行为,从而直观地设计应用程序 Repository\MVVM\MVP设计模式是WPF常用的系统架构 Auto

基于MVP模式实现四则运算器

基于MVP模式四则运算器 来到新东家,项目的框架采用的是MVP模式,刚来公司的时候,项目经理给予分配小任务,首先熟悉MVP模式,而后普通的四则运算器的实现使用MVP分层.这里主要回顾当时做任务时候的对于MVP模式的理解. 我是一名.Net开发工程师,使用语言为C#.微软在桌面客户端的开发上,提供的是WinForm和WPF两种基于.Net Framework的平台,现在的项目也是主要以Winform实现.传统Winform程序如果不予以分层的话,代码耦合十分严重.为解决代码耦合性问题,现在主流的分

设备资源管理系统-项目架构

SSH架构体系 架构测试表 架构体系 设备资源管理系统-项目架构

基于DR模式的keepalived主从模式高可用架构搭建

一:架构图示 2.keepalived是什么? Keepalived的作用是检测服务器的状态,如果有一台web服务器宕机 ,或工作出现故障,Keepalived将检测到,通过VRRP协议,将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后 Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器. 3.VRRP协议是什么? VRRP(Virtual Router Redundancy Protoc

Entity Framework Repository模式

Repository模式之前 如果我们用最原始的EF进行设计对每个实体类的“C(增加).R(读取).U(修改).D(删除)”这四个操作. 第一个:先来看看查询,对于实体类简单的查询操作,每次都是这样的过程会在代码中拥有大量的重复 极为类似的代码段. using (var db = new EFContext("EFContext")) { var persons = db.Persons.Where(t => t.PersonName == "aehyok")

LCLFramework框架之Repository模式

Respository模式在示例中的实际目的小结一下 Repository模式是架构模式,在设计架构时,才有参考价值: Repository模式主要是封装数据查询和存储逻辑: Repository模式实际用途:更换.升级ORM 引擎,不影响业务逻辑: Repository模式能提高测试效率,单元测试时,用Mock对象代替实际的数据库存取,可以成倍地提高测试用例运行速度. Repository与Dal的区别 Repository是DDD中的概念,强调Repository是受Domain驱动的,Re

关于Repository模式

定义(来自Martin Fowler的<企业应用架构模式>): Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects. 个人理解:Repository是一个独立的层,介于领域层与数据映射层(数据访问层)之间.它的存在让领域层感觉不到数据访问层的存在,它提供一 个类似集合的接口提供给领域层进行领域对象的访问.Reposit

Repository模式与UnitOfWorks模式的运用

软件开发就像是一个江湖,而设计模式就是一本高深的秘籍每读一次.用一次.想一次都能得到新的领悟,让我们的设计技能有所提高.开始时我们可能会“为了模式而模式”,让代码变得乱78糟甚至难以让人理解,但随着设计能力的提高与模式的运用和理解,慢慢地我们可能会忘掉模式随心所欲,此时再读读代码或者你已经发现自己的工程已融合模式之美—"模式为设计而生,设计为需求而活".在开篇突然想分享一下这10几年用模式的一点小小的领悟. IRepository 与 IUnitOfWork 在2011年我曾在Code