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 对象。

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ABP 应用程序中,您可以使用 Dapper 和 Entity Framework Core 两种 ORM 工具之一,或者甚至可以同时使用它们来访问数据库。以下是如何在 ABP 应用程序中同时使用 Dapper 和 Entity Framework Core 的步骤: 1.添加 Dapper 和 Entity Framework Core 的依赖项 在您的 ABP 应用程序中,您需要添加 Dapper 和 Entity Framework Core 的依赖项。您可以通过 NuGet 包管理器或手动编辑项目文件添加这些依赖项。添加 Dapper 和 Entity Framework Core 的依赖项后,您需要在 `Startup.cs` 文件中配置它们。 2.配置 Dapper 和 Entity Framework Core 在 `Startup.cs` 文件中,您需要配置 Dapper 和 Entity Framework Core。以下是一个示例: ```csharp public void ConfigureServices(IServiceCollection services) { // Add Dapper services.AddScoped<IDbConnection>(x => new SqlConnection(Configuration.GetConnectionString("Default"))); // Add Entity Framework Core services.AddAbpDbContext<MyProjectDbContext>(options => { options.AddDefaultRepositories(includeAllEntities: true); }); } ``` 在上面的代码中,我们使用 `AddScoped` 方法将 `IDbConnection` 注册为一个服务,并指定使用 `SqlConnection` 类创建连接。然后,我们使用 `AddAbpDbContext` 方法将 `MyProjectDbContext` 注册为一个服务,并指定包含所有实体。 3.编写 Dapper 和 Entity Framework Core 的查询 在您的应用程序中,您可以使用 Dapper 和 Entity Framework Core 的查询来访问数据库。以下是一个示例: ```csharp public class MyService : ITransientDependency { private readonly IDbConnection _connection; private readonly IRepository<MyEntity> _repository; public MyService(IDbConnection connection, IRepository<MyEntity> repository) { _connection = connection; _repository = repository; } public async Task<MyEntity> GetEntity(int id) { // Use Dapper var entity = await _connection.QueryFirstOrDefaultAsync<MyEntity>("SELECT * FROM MyEntities WHERE Id = @Id", new { Id = id }); // Use Entity Framework Core entity = await _repository.GetAsync(id); return entity; } } ``` 在上面的代码中,我们注入 `IDbConnection` 和 `IRepository<MyEntity>`,并在 `GetEntity` 方法中使用它们来执行 Dapper 和 Entity Framework Core 的查询。 需要注意的是,使用 Dapper 和 Entity Framework Core 的查询时,您需要务必遵循正确的事务处理和连接管理方式,以确保应用程序的数据完整性和性能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值