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=,
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 = ,
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 == ).FirstOrDefault();
db.Persons.Remove(person);
db.SaveChanges();
}

第四个:同理,修改操作如下。

            using (var db = new EFContext())
{
var person = db.Persons.Where(m => m.PersonId == ).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 ;
} public TEntity GetByKey(object key)
{
return Entities.Find(key);
}
}

5.简单调用

可以看到就这样即可进行调用处理。

总结

简单的项目分层,这里只是简单的处理分层,并没有真正意义上的。仅供参考。

简单测试项目下载链接地址

Entity Framework 5.0基础系列目录

Entity Framework Repository模式的更多相关文章

  1. Entity Framework 更新模式之Attach与EntityState.Modified模式的区别

    数据库中有一个City表 初始时数据: 实体类与Fluent Api配置映射 public class City { public int Id { get; set; } public string ...

  2. Entity Framework浅析

    1.Entity Framework简介 http://www.cnblogs.com/aehyok/p/3315991.html 2.Entity Framework DBFirst尝试http:/ ...

  3. Entity Framework 5.0基础系列

    1.Entity Framework简介 http://www.cnblogs.com/aehyok/p/3315991.html 2.Entity Framework DBFirst尝试http:/ ...

  4. 在Entity Framework 4.0中使用 Repository 和 Unit of Work 模式

    [原文地址]Using Repository and Unit of Work patterns with Entity Framework 4.0 [原文发表日期] 16 June 09 04:08 ...

  5. Generic repository pattern and Unit of work with Entity framework

    原文 Generic repository pattern and Unit of work with Entity framework Repository pattern is an abstra ...

  6. 关于Repository模式

    定义(来自Martin Fowler的<企业应用架构模式>): Mediates between the domain and data mapping layers using a co ...

  7. [转]关于Repository模式

    原文链接:关于Repository模式 定义(来自Martin Fowler的<企业应用架构模式>): Mediates between the domain and data mappi ...

  8. 重新认识了下Entity Framework

    什么是Entity Framework Entity Framework是一个对象关系映射O/RM框架. Entity Framework让开发者可以像操作领域对象(domain-specific o ...

  9. Entity Framework 笔记(一)

    Entity Framework概述 EF是一个对象关系映射(ORM)框架,允许开发人员使用特定于域的对象关系型数据,开发人员通常不需要编写大量的数据访问代码.使用EF,开发者可以利用LINQ进行查询 ...

随机推荐

  1. unity3d NGUI制作角色展示框

    最近在搞赛车漂移,所以一直没有更新博客 现在已经实现圈数检测.复位点检测.反向检测等功能 本来准备写成三篇文章的,太忙了,等过段时间不忙了在写吧 今天有朋友问我3D角色怎么给他固定在一个框里面 这个功 ...

  2. 从实用主义深入理解c++虚函数

    记得几个月前看过C++虚函数的问题,当时其实就看懂了,最近笔试中遇到了虚函数竟然不太确定,所以还是理解的不深刻,所以想通过这篇文章来巩固下. 装逼一刻: 最近,本人思想发生了巨大的转变,在大学的时候由 ...

  3. webstorm调试Node的时候配置

    点击Edit Configurations的这个的配置:(不能点击是因为目前你选中的不是项目)

  4. [codevs 1051]接龙游戏(栈)

    题目:http://codevs.cn/problem/1051/ 分析: 当然单词查找树是可以的,但这题有更为简便的方法.可以先按字典序排序,然后弄一个栈,如果当前字串可以接到栈顶元素的后面,那么当 ...

  5. [c#基础]堆和栈

    前言 堆与栈对于理解.NET中的内存管理.垃圾回收.错误和异常.调试与日志有很大的帮助.垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不代表 ...

  6. [Bug]当IDENTITY_INSERT设置为OFF时,不能为表“xx”中的标识列插入显示的值

    写在前面 在设计数据库表时,将主键设置为了自增的.在使用linq to sql的时候,添加数据,出现此错误. 解决方案 找到linq to sql生成的**.dbml文件,在对应的表上面右键修改其属性 ...

  7. 解决 pathForResource 返回 nil的问题

    点击(此处)折叠或打开 NSString* path = [[NSBundle mainBundle] pathForResource:@"sample" ofType:@&quo ...

  8. 基于spring mvc的注解DEMO完整例子

    弃用了struts,用spring mvc框架做了几个项目,感觉都不错,而且使用了注解方式,可以省掉一大堆配置文件.本文主要介绍使用注解方式配置的spring mvc,之前写的spring3.0 mv ...

  9. 使用XML序列化器生成XML文件和利用pull解析XML文件

    首先,指定XML格式,我指定的XML格式如下: <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <message&g ...

  10. oracle存储过程执行中输出日志文件

    create or replace procedure p_outputdebug(a varchar2,b varchar2,c varchar2)is vFileName varchar2(100 ...