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. Angular JS 学习笔记(自定义服务:factory,Promise 模式异步请求查询:$http,过滤器用法filter,指令:directive)

    刚学没多久,作了一个小项目APP,微信企业号开发与微信服务号的开发,使用的是AngularJS开发,目前项目1.0版本已经完结,但是项目纯粹为了赶工,并没有发挥AngularJS的最大作用,这几天项目 ...

  2. ThinkPHP之验证码的使用

    ThinkPHP中已经提供了验证码的生成以及验证的功能.下面介绍如何使用验证码.编程的时候还是采用MVC的方式 View层 <!DOCTYPE html> <html> < ...

  3. jQuery使用之(二)设置元素的样式

    css是页面不能分隔的部分,jQuery中也提供了一些css相关的实用的办法.前面章节中有使用过 addClass()为元素添加css样式风格.本节主要介绍jQuery如何设置页面的样式风格.包括添加 ...

  4. javascript去掉字符串前后空格

    使用场景 当我们进行一些页面编辑时,字符串前后的空格,通常是无效的.因此需要在获取信息时,进行过滤. 比如: 输入:[空格][空格]a[空格]b[空格][空格][空格] 得到:a[空格]b 代码如下: ...

  5. CreateCompatibleDC与BitBlt 学习

    CreateCompatibleDC与BitBlt CreateCompatibleDC 创建一个与指定设备一致的内存设备描述表. HDC CreateCompatibleDC(HDC hdc //设 ...

  6. MVC学习Day02之校验

    MVC校验有两种方法: 方法一:自己动手写js---------略 方法二: l在View的页面中,首先指定页面强类型@model 类型 l使用Html.***For(model=>model. ...

  7. hdu1873优先队列

    #include<stdio.h> #include<queue> using namespace std; struct node { int id; int val; fr ...

  8. 图解Android - Android GUI 系统 (5) - Android的Event Input System

    Android的用户输入处理 Android的用户输入系统获取用户按键(或模拟按键)输入,分发给特定的模块(Framework或应用程序)进行处理,它涉及到以下一些模块: Input Reader: ...

  9. WebLogic10安装图文教程

    一 WebLogic安装 1.  打开WebLogic安装程序:oepe11_wls1031.exe(我们选用的是WebLogic 10.3g).如图1-1所示: 2. 进入WebLogic安装的欢迎 ...

  10. 【poj1740】 A New Stone Game

    http://poj.org/problem?id=1740 (题目链接) 男人八题之一 题意 对于n堆石子,每堆若干个,两人轮流操作,每次操作分两步,第一步从某堆中去掉至少一个,第二步(可省略)把该 ...