发文章
发文工具
撰写
网文摘手
文档
视频
思维导图
随笔
相册
原创同步助手
其他工具
图片转文字
文件清理
AI助手
留言交流
Repository模式之前
如果我们用最原始的EF进行设计对每个实体类的“C(增加)、R(读取)、U(修改)、D(删除)”这四个操作。
第一个:先来看看查询,对于实体类简单的查询操作,每次都是这样的过程会在代码中拥有大量的重复 极为类似的代码段。
using (var db = new EFContext("EFContext")) { var persons = db.Persons.Where(t => t.PersonName == "aehyok").OrderByDescending(t => t.PersonId).ToList(); foreach (var p in persons) { Console.WriteLine("The PersonName is {0} and Age {1}", p.PersonName, p.Age); } } Console.ReadLine();
第二个:对于实体类的添加操作。
using (var db = new EFContext()) { var stephen = new Person { PersonName="aehyok0001", Age=25, Address="深圳南山", Email="aehyok@163.com" }; db.Persons.Add(stephen); db.Persons.Attach(stephen); db.Entry(stephen).State = EntityState.Unchanged; ////同上面db.Persons.Attach(stephen);作用是一样的 var jeffrey = new Person { PersonName = "aehyok0002", Age = 25, Address = "深圳宝安", Email = "Leo@163.com" }; db.Entry(jeffrey).State = EntityState.Added; db.SaveChanges(); }
第三个:同理,删除操作如下。
using (var db = new EFContext()) { var person = db.Persons.Where(m => m.PersonId == 4).FirstOrDefault(); db.Persons.Remove(person); db.SaveChanges(); }
第四个:同理,修改操作如下。
以上基于一个实体类简单的CURD操作,当然对于查询千变万化。在数据访问层,我们可以专门的为每个类进行封装业务处理类,但是其中类与类之间相同或类似的代码段太多,对于编码人员来说,更是浪费时间,同样的代码,要在项目的不同使用地方,进行多次的复制修改几个代码字段即可使用,那么我们为什么不进行简单的封装处理,来让这一过程变得更加简单,且使我们的代码变得更为优雅,让开发人员的维护操作更为简单,也更易于扩展。基于以上考虑引出了我们的Repository设计模式。
Repository设计模式
在《企业架构模式》中,译者将Repository翻译为资源库。给出如下说明:通过用来访问领域对象的一个类似集合的接口,在领域与数据映射层之间进行协调。
那么基于Rspository模式,数据访问层无非就是对数据进行增删改查,其中增、删、改等我们可以抽象出来写一个公共的接口或抽象类来定义这些方法,并采用一个基类实现这些方法,这样该基类派生的子类都会继承增、删、改这些方法,这样我们就避免了每个实体都要重复实现这些方法。一句话概括就是:通过接口 泛型 与ORM结合 实现了数据访问层更好的复用。
Repository代码实现
1.EF实例数据操作上下文对象
主要进行初始化数据库,并进行设置自动更新数据库
public class EFContext:DbContext { public EFContext() : base("default") { Database.SetInitializer<EFContext>(new MigrateDatabaseToLatestVersion<EFContext,EFDbMigrationsConfiguration>()); } public DbSet<Member> Members { get; set; } public DbSet<Score> Scores { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); modelBuilder.Entity<Member>().HasMany(b => b.Scores); } } internal sealed class EFDbMigrationsConfiguration : DbMigrationsConfiguration<EFContext> { public EFDbMigrationsConfiguration() { AutomaticMigrationsEnabled = true;//任何Model Class的修改將會自动直接更新DB AutomaticMigrationDataLossAllowed = true; //可接受自动迁移期间的数据丢失的值 } }
2.BaseEntity类
BaseEntity类中定义了所有参加数据操作实体的公共属性,因此我们把该类定义为抽象类,作为派生类的的基类。
public abstract class BaseEntity { [Key] public Guid Id { get; set; } public DateTime CreateDate { get; set; } public BaseEntity() { Id = Guid.NewGuid(); CreateDate = DateTime.Now; } }
3.Repository模式中最底层的接口实现IRepository
我们对实体的公共操作部分,提取为IRepository接口,比如常见的增加,删除、修改等方法。
public interface IRepository<TEntity> where TEntity:BaseEntity { DbSet<TEntity> Entities { get; } //增加单个实体 int Insert(TEntity entity); //增加多个实体 int Insert(IEnumerable<TEntity> entities); //更新实体 int Update(TEntity entity); //删除 int Delete(object id); //根据逐渐获取实体 TEntity GetByKey(object key); }
其中的接口方法的定义,也会根据具体项目中业务,来进行定义适应自身的方法。具有一定的灵活性
我们发现接口的泛型TEntity有一个约束需要继承BaseEntity,BaseEntity就是把实体中公共的属性抽取出来,比如:Id(主键),CreateDate(创建时间)等。
4.Repository模式中基于接口的抽象类EFRepositoryBase
我们用一个抽象类EFRepositoryBase来实现接口中的方法,这样派生的类都具有接口中定义的方法,也防止EFRepositoryBase直接被实例化。
public abstract class EFRepositoryBase<TEntity>:IRepository<TEntity> where TEntity:BaseEntity { EFContext EF = new EFContext(); public DbSet<TEntity> Entities { get { return EF.Set<TEntity>(); } } public int Insert(TEntity entity) { Entities.Add(entity); return EF.SaveChanges(); } public int Insert(IEnumerable<TEntity> entities) { Entities.AddRange(entities); return EF.SaveChanges(); } public int Update(TEntity entity) { EF.Entry(entity).State = EntityState.Modified; return EF.SaveChanges(); } public int Delete(object id) { ///删除操作实现 return 0; } public TEntity GetByKey(object key) { return Entities.Find(key); } }
5.简单调用
可以看到就这样即可进行调用处理。
总结
简单的项目分层,这里只是简单的处理分层,并没有真正意义上的。仅供参考。
简单测试项目下载链接地址
Entity Framework 5.0基础系列目录
来自: 昵称10504424 > 《工作》
0条评论
发表
请遵守用户 评论公约
DDD领域驱动设计初探(2):仓储Repository(上)
2、站在架构的层面,仓储解耦了领域层和ORM之间的联系,这一点也就是很多人设计仓储模式的原因,比如我们要更换ORM框架,我们只需要改变...
MVC实用架构设计(三)——EF-Code First(1):Repository,UnitOfWork,DbContext
Data 2 { 3 /// <summary> 4 /// 数据单元操作接口 5 /// </summary> 6 public interface IUnitOfWorkContext : IUnitOfWor...
Repository模式
public class DataContext: DbContext,IDbContext{ public new IDbSet<TEntity> Set<TEntity>() where TEntity : class { return base.public class RepositoryService<TEntity>:IRe...
MVC3+EF4.1学习系列(八)
public StudentRepository(SchoolContext context) { this.context = context;public void Save() { context.public GenericRepository(...
应用程序框架实战二十二 : DDD分层架构之仓储(层超类型基础篇)
Ef { /// <summary> /// 仓储 /// </summary> /// <typeparam name=''''''''TEntity''''''''>实体类型</typep...
MVC中的Repository模式
} public void Delete(TEntity entity) { if (dbContext.//在执行子类构造函数之前,先执行基类Repository<Book>的构造函数 publi...
跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(二)Models(ORM)
跟我学MVC系列(Repository模式、LINQ、EF、IOC框架Castle、JQuery、AJAX)(二)Models(ORM)在《企业架构模式》中,译者将Repository...
程序员应知应会之Spring Data Jpa为什么不用写@Repository注解?
程序员应知应会之Spring Data Jpa为什么不用写@Repository注解?大家知道,在Springboot+Spring Data Jpa的项目里,dao层只需要继承JpaR...
保存|DDD之代码架构
DDD之代码架构荒腔走板。DDD结合整洁架构可以让依赖变得清晰,比三层架构有更好的“高内聚,低耦合”特性。但DDD可以,DDD可以把业务全...
微信扫码,在手机上查看选中内容