ABP理论学习之EntityFramework集成
本篇目录
ABP可以使用任何ORM框架工作,并且已经内置了EntityFramework集成。这篇文章会解释如何在ABP中使用EntityFramework。阅读本文的前提是假设你已经熟悉了EF的基本知识。
Nuget包###
在ABP中使用EF作为ORM的Nuget包是Abp.EntityFramework。你应该将它添加到应用程序中。最好在应用程序中分离的程序集(dll)中实现EntityFramework,并让该程序集依赖Abp.EntityFramework包。
创建DbContext###
要使用EF工作,你应该为应用程序定义一个DbContext。定义DbContext的一个例子如下所示:
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);
}
}
除了派生自AbpDbContext而不是DbContext之外,它还是一个常规的DbContext。AbpDbContext的构造函数有很多重载。你可以使用你需要的那个。
EntityFramework可以以一种惯例的方式将类映射到数据库中对应的表。除非你要做一些自定义的东西,否则你不需要做任何配置。在这个例子中,我们将实体映射到不同的表,默认地,Task实体会映射到Tasks表。但是我们将它改成了StsTasks表,这里没有用数据注解特性配置,我更喜欢使用流畅的配置。你也可以选择你喜欢的方式。
仓储###
ABP提供了一个基类EfRepositoryBase可以轻松地实现仓储。为了实习IRepository接口,只需要从这个类中派生仓储就可以了。但是最好创建你自己的继承了EfRepositoryBase的基类。这样,你就可以给仓储轻松地添加一些共享的方法了。
仓储基类
一个简单任务系统(SimpleTaskSystem)应用的所有仓储的基类例子如下所示:
//所有仓储的基类
public class SimpleTaskSystemRepositoryBase<TEntity, TPrimaryKey> : EfRepositoryBase<SimpleTaskSystemDbContext, TEntity, TPrimaryKey>
where TEntity : class, IEntity<TPrimaryKey>
{
public SimpleTaskSystemRepositoryBase(IDbContextProvider<SimpleTaskSystemDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
//为所有的仓储添加一些公共的方法
}
//Id为整数的实体的快捷方式
public class SimpleTaskSystemRepositoryBase<TEntity> : SimpleTaskSystemRepositoryBase<TEntity, int>
where TEntity : class, IEntity<int>
{
public SimpleTaskSystemRepositoryBase(IDbContextProvider<SimpleTaskSystemDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
//不要在这里添加任何方法,在上面的方法中添加(因为该方法继承了上面的方法)
}
注意我们是从EfRepositoryBase<SimpleTaskSystemDbContext, TEntity, TPrimaryKey>继承的。这就声明了ABP在仓储中使用的数据上下文是SimpleTaskSystemDbContext。
默认实现仓储
你不需要为实体类创建仓储,只需要使用预定义的仓储方法。例子:
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并使用仓储中的Insert方法。使用这种方法,你可以轻松地注入 IRepository(或者IRepository<TEntity,TPrimaryKey>),然后使用预定义的方法。所有预定义的方法列表,请查看仓储文档。
自定义仓储方法
要实现一个自定义的仓储,只需要从上面创建的仓储基类中派生就可以了。
假设我们有一个Task(任务)实体,该任务可以派给一个Person(人)实体,而且Task实体有这么几种状态,包括new,assigned,completed等等。我们可能需要写一个自定义方法来根据一些条件和AssignedPerson来获取任务的列表。看下面的代码:
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接口,然后实现了它。GetAll()方法返回了IQueryable,然后使用给定的参数添加了一些 Where过滤。最后使用 ToList()获得Tasks的列表。
你也可以在仓储方法中使用Context对象到达DbContext,然后可以直接使用EF基础设施了。
仓储应该获得一个IDbContextProvider。这样的话,我们就可以在单元测试中轻松地注入一个伪造的DbContext提供者了。在运行时,ABP会自动地注入正确的DbContext提供者。
阅读其他###
你也可以查看仓储文档获取更多关于仓储的知识。
ABP理论学习之EntityFramework集成的更多相关文章
- ABP文档 - EntityFramework 集成
文档目录 本节内容: Nuget 包 DbContext 仓储 默认仓储 自定义仓储 特定的仓储基类 自定义仓储示例 仓储最佳实践 ABP可使用任何ORM框架,它已经内置了EntityFrame(以下 ...
- ABP理论学习之SignalR集成
返回总目录 本篇目录 介绍 安装 建立连接 内置功能 你自己的SignaR代码 介绍 Abp.Web.SignalR 使得在基于ABP的应用程序中使用 SignalR相当容易.查看SignalR文档获 ...
- ABP理论学习之NHibernate集成
返回总目录 本篇目录 Nuget包 配置 实体映射 仓储 仓储基类 实现仓储 自定义仓储方法 阅读其他 ABP可以使用任何ORM框架工作,并且已经内置了NHibernate集成.这篇文章会解释如何在A ...
- ABP理论学习之OWIN集成
返回总目录 如果你的应用中使用了OWIN,那么需要在主项目(一般来说是指Web项目)中添加Abp.Owin的nuget包,然后像下面那样在OWIN的 Startup文件中调用 UseAbp()扩展方法 ...
- ABP理论学习之OData集成(新增)
返回总目录 本篇目录 介绍 安装 创建控制器 例子 样例项目 介绍 OData在其官网的定义是: 允许以一种 简单且标准的方式创建和使用可查询的.可互操作的RESTful APIs. 在ABP中也可以 ...
- ABP官方文档翻译 9.1 EntityFramework集成
EntityFramework集成 Nuget包 DbContext 仓储 默认仓储 自定义仓储 应用特定的基础仓储类 自定义仓储示例 仓储最佳实践 事务管理 数据存储 ABP可以使用ORM框架,它内 ...
- ABP理论学习之数据过滤器
返回总目录 本篇目录 介绍 预定义过滤器 关闭过滤器 开启过滤器 设置过滤器参数 定义自定义过滤器 其他ORM 介绍 软删除模式通常用于不会真正从数据库删除一个实体而是仅仅将它标记为"已删除 ...
- ABP理论学习之Web API控制器(新增)
返回总目录 本篇目录 介绍 AbpApiController基类 本地化 审计日志 授权 工作单元 其他 介绍 ABP通过Abp.Web.ApiNuget包集成了 ASP.NET Web API控制器 ...
- ABP理论学习之Javascript API(理论完结篇)
返回总目录 本篇目录 Ajax Notification Message UI block和busy 事件总线 Logging 其他工具功能 说在前面的话 不知不觉,我们送走了2015,同时迎来了20 ...
随机推荐
- 攻城狮在路上(陆)-- hadoop分布式环境搭建(HA模式)
一.环境说明: 操作系统:Centos6.5 Linux node1 2.6.32-431.el6.x86_64 #1 SMP Fri Nov 22 03:15:09 UTC 2013 x86_64 ...
- Redis3重建Cluster
1.关闭cluster全部节点2.删除所有nodes.conf文件3.开启全部节点4.依次flushall5.重建集群即可 Share the post "Redis3重建Cluster&q ...
- Qt中暂停线程的执行
在线程中定义一个信号量 QMutex pause; 把run()函数中循环执行的部分用信号量pause锁住: void run() { while(1) { pause.lock(); //循环执行的 ...
- Redis学习总结(1)——数据持久化
以前研究Redis的时候,很多东西都不太明白,理解得也不太深,现在有时间重新拾起来看看,将一些心得记录下来,希望和大家一起探讨. 一.简介 Redis是一个单线程高可用的Key-Value存储系统,和 ...
- node.js之开发环境搭建
一.安装linux系统 (已安装linux可跳此步骤) 虚拟机推荐选择:VirtualBox 或者 Vmware (专业版永久激活码:5A02H-AU243-TZJ49-GTC7K-3C61N) 我这 ...
- [翻译svg教程]svg学习系列 开篇
目录 [翻译svg教程]svg学习系列 开篇 [翻译svg教程 ]svg 的坐标系统 [翻译svg教程]svg 中的g元素 [翻译svg教程]svg中矩形元素 rect [翻译svg教程]svg中的c ...
- View的弹性滑动
View的弹性滑动 实现弹性滑动的思想:将一次大的滑动分成若干次小的滑动并在一个时间段内完成,具体的实现方式有很多,如通过Scroller.Handler#postDelayed以及Thread#sl ...
- mysql安装流程
一.配置MySQL数据库 1.解压绿色版mysql,如下图 二.安装服务 1.运行cmd(管理员版本,否则没有权限),如下图 2.运行命令mysqld –install安装服务,如下图: 如果不需要m ...
- grunt-connect-proxy解决开发时跨域问题
最近的项目中前后端是完全分离开发的,前端用grunt管理项目.这样就会导致一个问题:开发时前端调用后台的接口时因为不在一个服务器,所以会出现跨域问题.但是也不能用JSONP或CROS方式实现真正的跨域 ...
- 常用的107条Javascript
1. document.write( " "); 输出语句 2.JS中的注释为// 3.传统的HTML文档顺序是:document- >html- >( ...