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. 关于UITextView / String的尺寸

    关于UITextView以及String的尺寸动态获取 iOS7开始,UITextView设置text后不会立即反映到contentSize属性,而是在父容器layoutSubviews时进行cont ...

  2. PRML读书会第二章 Probability Distributions(贝塔-二项式、狄利克雷-多项式共轭、高斯分布、指数族等)

    主讲人 网络上的尼采 (新浪微博: @Nietzsche_复杂网络机器学习) 网络上的尼采(813394698) 9:11:56 开始吧,先不要发言了,先讲PRML第二章Probability Dis ...

  3. Gt9xx芯片,在规格书+Linux驱动的基础上,移植为USB裸机经验。直接用开发板,不去碰硬件的坑。

    1,用内核代码和规格书来印证数据格式: //命令3字节,IC地址 u8 end_cmd[] = {GTP_READ_COOR_ADDR >> , GTP_READ_COOR_ADDR &a ...

  4. c# r3 inline hook

    前言 老婆喜欢在QQ游戏玩拖拉机,且安装了一个记牌器小软件,打开的时候弹出几个IE页面加载很多广告,于是叫我去掉广告.想想可以用OD进行nop填充,也可以写api hook替换shellexecute ...

  5. 《TCP/IP详解卷1:协议》第6章 ICMP:Internet控制报文协议-读书笔记

    章节回顾: <TCP/IP详解卷1:协议>第1章 概述-读书笔记 <TCP/IP详解卷1:协议>第2章 链路层-读书笔记 <TCP/IP详解卷1:协议>第3章 IP ...

  6. AngularJS开发指南6:AngularJS表单详解

    表单控件(input, select, textarea )是用来获取用户输入的.表单则是一组有联系的表单控件的集合. 用户能通过表单和表单控件提供验证的服务,知道自己的输入是否合法.这样能让用户交互 ...

  7. new-nav-css

    header:before, header:after ,.navigation:before, .navigation:after,.nav-row:before, .nav-row:after,. ...

  8. Linux_日志信息

    一.httpd日志:/var/log/httpd1.软件位置:whereis httpd2.配置文件位置:/etc/httpd/conf/httpd.conf 二.mysql日志:/var/log 查 ...

  9. 【BZOJ】3527: [Zjoi2014]力(fft+卷积)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3527 好好的一道模板题,我自己被自己坑了好久.. 首先题目看错.......什么玩意.......首 ...

  10. FZU2082树链剖分

    简单题. #include<queue> #include<stack> #include<cmath> #include<cstdio> #inclu ...