本文翻译自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 对象。

转载于:https://www.cnblogs.com/dehai/p/4713549.html

ABP 基础设施层——集成 Entity Framework相关推荐

  1. Asp.Net MVC 模型(使用Entity Framework创建模型类)

    Asp.Net MVC 模型(使用Entity Framework创建模型类) 这篇教程的目的是解释在创建ASP.NET MVC应用程序时,如何使用Microsoft Entity Framework ...

  2. 使用 ASP.NET Core, Entity Framework Core 和 ABP 创建N层Web应用 第二篇

    介绍 这是"使用 ASP.NET Core ,Entity Framework Core 和 ASP.NET Boilerplate 创建N层 Web 应用"系列文章的第二篇.以下 ...

  3. ABP官方文档翻译 9.2 Entity Framework Core

    Entity Framework Core 介绍 DbContext 配置 在Startup类中 在模块PreInitialize方法中 仓储 默认仓储 自定义仓储 应用程序特定基础仓储类 自定义仓储 ...

  4. 自定义Unity对象生命周期管理集成ADO.NET Entity Framework

    在Unity中,从Unity 取得的实例为 Transient.如果你希望使用多线程方式,就需要在组成时使用lifecycle参数,这时候取出的组件就不再是同一个了.在Unity IOC中,它支持我们 ...

  5. ABP .Net Core Entity Framework迁移使用MySql数据库

    一.迁移说明 ABP模板项目Entity Framework Core默认使用的是Sql Server,也很容易将数据库迁移到MySQL,步骤如下. 二.迁移MySQL步骤 1. 下载项目 请到 ht ...

  6. abp mysql .net core_ABP .Net Core Entity Framework迁移使用MySql数据库

    一.迁移说明 ABP模板项目Entity Framework Core默认使用的是Sql Server,也很容易将数据库迁移到MySQL,步骤如下. 二.迁移MySQL步骤 1. 下载项目 请到 ht ...

  7. abp.net mysql_ABP .Net Core Entity Framework迁移使用MySql数据库

    一.迁移说明 ABP模板项目Entity Framework Core默认使用的是Sql Server,也很容易将数据库迁移到MySQL,步骤如下. 二.迁移MySQL步骤 1. 下载项目 请到 ht ...

  8. 手把手引进门之 ASP.NET Core Entity Framework Core(官方教程翻译版 版本3.2.5)

    以下是手把手引进门教程,基于 ASP.NET Core, Entity Framework Core ,ABP 框架 创建Web 应用, PS: 自带自动的测试模块哦. 样例下载 (上 github  ...

  9. Entity Framework的启动速度优化

    最近开发的服务放到IIS上寄宿之后,遇到一些现象,比如刚部署之后,第一次启动很慢:程序放置一会儿,再次请求也会比较慢.比如第一个问题,可以解释为初次请求某一个服务的时候,需要把程序集加载到内存中可能比 ...

最新文章

  1. python使用matplotlib可视化折线图、在可视化图像中同时绘制多条折线图
  2. 干货 | 纽约大学陈溪: AlphaGo Zero技术演进的必然性(附PPT)
  3. Oracle Golden Gate 系列十七 -- GG 一对多 real-time data distribution 说明 与 示例
  4. 成功解决ImportError: cannot import name ‘ft2font‘ from ‘matplotlib‘
  5. Docker + Intellij IDEA,提升 10 倍生产力!
  6. 聚美优品范忱:我是如何将用户推荐准确率提升 10% 的?
  7. AngularJS学习笔记(一)
  8. 用Python编写博客导出工具
  9. hdu1068 Girls and Boys --- 最大独立集
  10. 2020年关于SAP知识问答的一个新的尝试
  11. 【免费毕设】ASP.NET 网上选课系统的设计与实现(源代码+lunwen)
  12. java inputstream长度_Java InputStream.available获取数据流字节长度大小
  13. #怎样获取当前时间和时区_JDK1.8新增日期时间类型
  14. pd虚拟机专用windows系统镜像(m1/intel)「新增:Intel Mac win7专业版懒人包镜像」
  15. 机器学习深度学习面试题——Python基础知识
  16. 2019-03-02 致虚极守静笃 读老子《道德经》有感
  17. CSS animation 属性
  18. 通盘无妙招与神来之笔的两种推广策略
  19. KVM虚拟化介绍和安装使用方法
  20. 导数和微分的区别与联系

热门文章

  1. Zoom Capability
  2. 流水账之都市:我是一个客居者
  3. Modelsim+Debussy联合使用
  4. 微软拼音输入法2007状态栏无法显示!
  5. 使用字典编码每个字再编码每句话不知对nlp是否有帮助(深度大脑)
  6. 从源码分析DEARGUI之add_slider_float-4和add_slider_int-4
  7. 使用此代码可以解决python包导入路径问题?
  8. webpack相关配置
  9. 聊聊 scala 的模式匹配
  10. 贝塞尔曲线与CAShapeLayer的关系以及Stroke动画