集成 Entity Framework
ABP 基础设施层——集成 Entity Framework
本文翻译自ABP的官方教程《EntityFramework Integration》,地址为:http://aspnetboilerplate.com/Pages/Documents/EntityFramework-Integration
ABP 可以与任何 ORM 框架协同工作,它内置了对 EntityFramework 的集成支持。本文将介绍如何在 ABP 中使用 EntityFramework。本文假定你已经初步掌握了EntityFramework。
译者注:怎么才算初步掌握了 EntityFramework 呢?译者认为应当懂得使用 Code First 模式进行CRUD。
1 Nuget 包
要在 ABP 中使用 EntityFramework 作为 ORM 框架的话,需要到 Nuget 上下载一个名为 Abp.EntityFramework的包。比较好的做法是:新建一个独立的程序集 (dll),然后在这个程序集中调用这个包和 EntityFramework。
2 创建 DbContext(Creating DbContext)
要使用 EntityFramework,首先需要定义一个 DbContext 类。下面是一个DbContex 类的示例:

public class SimpleTaskSystemDbContext : AbpDbContext
{
public virtual IDbSet<Person> People { get; set; } public virtual IDbSet<Task> Tasks { get; set; }
public SimpleTaskSystemDbContext()
: base("MyConnectionStringName")
{ } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Person>().ToTable("StsPeople");
modelBuilder.Entity<Task>().ToTable("StsTasks").HasOptional(t=> t.AssignedPerson);
} }

上面的 SimpleTaskSystemDbContext 本质上是一个 DbContext 类,它派生自 AbpDbContext,而不是 DbContext。AbpDbContext 提供了很多重载的构造函数,如果需要的话,我们可以使用它。EntityFramework 可以使用约定的方式来映射实体和数据表。除非你想进行自定义映射,否则你甚至不需要做任何配置。在上例中,我们将实体映射到了不同的表中。默认情况下(按照约定优先于配置的原则,会默认采用约定的方式),Task 实体会映射到 Tasks 表,但在这里我们将它映射到了 StsTasks 表。相比起使用 Data Annotation 模式来进行自定义映射,我更喜欢使用 Fluent API 模式。当然,你可以选择你所喜欢的模式,这里没有特别的限制。
3 仓储(Repositories)
ABP 提供了一个名为 EfRepositoryBase 的基类,这使得实现仓储变得简单快捷。要实现 IRepository 接口,你只需要从这个基类进行派生即可。但是更好的做法是,自定义一个派生自 EfRepositoryBase 的基类,然后在这个基类中添加一些通用的方法。这样做的好处是,所有派生自这个基类的仓储都继承了这些通用方法。
(1)应用程序专用的仓储基类(Application specific base repository class)
在下面的例子中,我们定义了一个名为 SimpleTaskSystem 仓储基类,这个类是此应用程序所专用的。

// 应用程序中的所有仓储的基类
public class SimpleTaskSystemRepositoryBase<TEntity, TPrimaryKey> : EfRepositoryBase<SimpleTaskSystemDbContext, TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
{
public SimpleTaskSystemRepositoryBase(IDbContextProvider<SimpleTaskSyst emDbContext> dbContextProvider)
: base(dbContextProvider)
{ } //添加仓储基类的通用方法 } public class SimpleTaskSystemRepositoryBase<TEntity> : SimpleTaskSystemRepositoryBase<TEntity, int>
where TEntity : class, IEntity<int>
{
public SimpleTaskSystemRepositoryBase(IDbContextProvider<SimpleTaskSyst emDbContext> dbContextProvider)
: base(dbContextProvider)
{ } // 不 要 在 这 里 添 加 任 何 通 用 方 法 ,通 用 方 法 应 当 被添加到 上 面 的 基 类 中(MyRepositoryBase<TEntity, TPrimaryKey>) }

需 要 注 意 的 是 , 我 们 继 承 了 基 类EfRepositoryBase<SimpleTaskSystemDbContext, TEntity, TPrimaryKey>。这相当于做了一个声明,它会让 ABP 在仓储中调用 SimpleTaskSystemDbContext。
(2)仓储实现(Implementing a repository)
如果你只想使用预定义的仓储方法的话,你甚至不需要为实体创建仓储类。如下所示:

public class PersonAppService : IPersonAppService
{
private readonly IRepository<Person> _personRepository; public PersonAppService(IRepository<Person> personRepository)
{
_personRepository = personRepository;
} public void CreatePerson(CreatePersonInput input)
{
person = new Person { Name = input.Name, EmailAddress = input.EmailAddress };
_personRepository.Insert(person);
}
}

PersonAppService类采用构造函数注入的方式注入了一个IRepository<Person>对象,然后调用了预定义的 Insert 方法。采用这种方式,你可以方便地注入IRepository<TEntity> (或者 IRepository<TEntity, TPrimaryKey>)对象,然后使用预定义的方法。查看仓储文档以获得预定义方法的列表。
(3)自定义仓储(Custom repositories)
要实现自定义仓储,只要从上面所创建的应用程序专用的仓储基类(SimpleTaskSystemRepositoryBase)派生即可。
假定我们有一个名为 Task 的实体,它可以被赋予 Person 实体。Task 有一个状态属性(值为新建、已分配、已完成等)。我们需要编写一个自定义方法,这个方法能根据某些条件获取 Task 列表,并且使得 Task 的 AssisgnedPerson 属性可以在一次数据库查询中被加载(使用 EntityFramework 的贪婪加载方法 Include)。如下所示:

public interface ITaskRepository : IRepository<Task, long>
{
List<Task> GetAllWithPeople(int? assignedPersonId, TaskState? state);
} public class TaskRepository : SimpleTaskSystemRepositoryBase<Task, long>, ITaskRepository
{
public TaskRepository(IDbContextProvider<SimpleTaskSystemDbContext> dbContextProvider)
: base(dbContextProvider)
{
} public List<Task> GetAllWithPeople(int? assignedPersonId, TaskState? state)
{
var query = GetAll();
if (assignedPersonId.HasValue)
{
query = query.Where(task => task.AssignedPerson.Id == assignedPersonId.Value);
}
if (state.HasValue)
{
query = query.Where(task => task.State == state);
}
return query
.OrderByDescending(task => task.CreationTime)
.Include(task => task.AssignedPerson)
.ToList();
}
}

我们首先定义了一个名为 ITaskRepository 的接口,紧接着定义了一个名为 TaskRepository 的类来实现它。预定义方法 GetAll()返回了一个 IQueryable<Task> 对象,接着我们将参数放入到 Where 筛选器中,最后调用 ToList()来获得一个 Task 列表。此外,我们可以通过调用 base.Context 属性来获得一个 DbContext 对象,这样一来,你就可以直接使用 Entity Framework 的所有功能。
仓储类应当在构造函数中获取IDbContextProvider对象。通过这种方式,在单元测试的时候,我们可以很容易地注入一个虚拟的 DbContext Provider 对象;而在运行的时候,ABP 会根据配置注入相应的 DbContext Provider 对象。
集成 Entity Framework的更多相关文章
- ABP 基础设施层——集成 Entity Framework
本文翻译自ABP的官方教程<EntityFramework Integration>,地址为:http://aspnetboilerplate.com/Pages/Documents/En ...
- ABP框架系列之三:(Entity Framework Integration-实体框架集成)
ASP.NET Boilerplate can work with any O/RM framework. It has built-in integration with EntityFramewo ...
- 采用MiniProfiler监控EF与.NET MVC项目(Entity Framework 延伸系列1)
前言 Entity Framework 延伸系列目录 今天来说说EF与MVC项目的性能检测和监控 首先,先介绍一下今天我们使用的工具吧. MiniProfiler~ 这个东西的介绍如下: MVC Mi ...
- Entity Framework的启动速度优化
最近开发的服务放到IIS上寄宿之后,遇到一些现象,比如刚部署之后,第一次启动很慢:程序放置一会儿,再次请求也会比较慢.比如第一个问题,可以解释为初次请求某一个服务的时候,需要把程序集加载到内存中可能比 ...
- ASP.NET 5 和Entity Framework 7公告仓库
ASP.NET 5 有一个公告仓库来介绍ASP.NET 5和 Entity Framework 7的主要变更说明,这个对于日夜更新的项目来说,很多人经常会遇到问题但是不知道去哪里寻找帮助,很多同学在做 ...
- ADO.NET Entity Framework 在哪些场景下使用?
在知乎回答了下,顺手转回来. Enity Framework已经是.NET下最主要的ORM了.而ORM从一个Mapping的概念开始,到现在已经得到了一定的升华,特别是EF等对ORM框架面向对象能力的 ...
- Entity Framework 6 Database-first连接Oracle11g
Entity Framework 6 Database-first连接Oracle11g(图文细说) 本文发布地址:http://www.cnblogs.com/likeli/p/5577264.ht ...
- 分享基于Entity Framework的Repository模式设计(附源码)
关于Repository模式,在这篇文章中有介绍,Entity Framework返回IEnumerable还是IQueryable? 这篇文章介绍的是使用Entity Framework实现的Rep ...
- 《Entity Framework 6 Recipes》翻译系列 (1) -----第一章 开始使用实体框架之历史和框架简述
微软的Entity Framework 受到越来越多人的关注和使用,Entity Framework7.0版本也即将发行.虽然已经开源,可遗憾的是,国内没有关于它的书籍,更不用说好书了,可能是因为EF ...
随机推荐
- 移动web:翻页场景动画
在移动web,特别是在微信中,经常看到一种翻页动画效果,也称为场景动画. 一页一页的翻过,像在看书,每页的内容以各种"炫酷"的效果出现在你的眼里,配上一首动听的音乐,你有没有喜欢上 ...
- 【Spring】Spring学习笔记-01-入门级实例
听说当前Spring框架很流行,我也准备好好学学Spring开发,并将学习的过程和大家分享,希望能对志同道合的同学有所帮助. 以下是我学习Spring的第一个样例. 1.Spring开发环境的搭建 我 ...
- 解决Nginx的connect() to 127.0.0.1:8080 failed (13: Permission denied) while connect
在进行Nginx+Tomcat 负载均衡的时候遇到了这个权限问题,在error.log日志中.我们能够看到例如以下: connect() to 127.0.0.1:8080 failed (13: P ...
- 一个小的日常实践——高速Fibonacci数算法
上得厅堂.下得厨房.写得代码,翻得围墙,欢迎来到睿不可挡的每日一小练! 题目:高速Fibonacci数算法 内容:先说说Fibonacci数列,它的定义是数列:f1,f2....fn有例如以下规律: ...
- ArcSDE SDK For Java二次开发介绍、演示样例
在一个工作中,遇到了须要java后台来查询ArcGIS 中用到的Oracle数据库空间数据,因为对ArcGIS空间数据首次接触,仅仅知道Oracle能够使用ST_GEOMETRY字段存储,例如以下图 ...
- (2) 用DPM(Deformable Part Model,voc-release4.01)算法在INRIA数据集上训练自己的人体检測模型
步骤一,首先要使voc-release4.01目标检測部分的代码在windows系统下跑起来: 參考在window下执行DPM(deformable part models) -(检測demo部分) ...
- linux于test
订购具体解释
測试标志 代表意义 文件名称.文件类型 -e 该文件名称是否存在 -f 该文件名称是否存在且为file -d 该文件名称是否存在且为文件夹 -b 该文件名称是否存在且为一个block -c 该文件名称 ...
- ignore,neglect,omit,overlook
一:简介——ignore :通常指有意不顾,或不理显而易见的事物.neglect :侧重指有意的忽略或忽视,也可指粗心与疏忽.omit :指有意或无意地忘记做某事,也指删去被视作不重要.不合意的东西. ...
- GoldenGate组态(四)它veridata组态
GoldenGate组态(四)它veridata组态 环境: Item Source System Target System Platform Red Hat Enterprise Linux Se ...
- Linux下find命令具体解释
1. find命令 linux的find命令用来查找文件,功能非常强大, 能够通过时间, 用户组, 文件名称, 文件类型, 权限,大小等来查找对应文件. 2. find的使用方法 通过find --h ...