ABP框架系列之三:(Entity Framework Integration-實體框架集成)


ASP.NET Boilerplate can work with any O/RM framework. It has built-in integration with EntityFramework. This document will explain how to use EntityFramework with ASP.NET Boilerplate. It's assumed that you're already familar with EntityFramework in a basic level.

ASP.NET樣板可以與任何O / RM工作框架。它具有內置的集成EntityFramework。本文檔將解釋如何使用EntityFramework ASP.NET樣板。假定你已經熟悉了基本的EntityFramework。

Nuget Package

Nuget package to use EntityFramework as O/RM in ASP.NET Boilerplate is Abp.EntityFramework. You should add it to your application. It's better to implement EntityFramework in a seperated assembly (dll) in your application and depend on that package from this assembly. 

使用EntityFramework NuGet包在ASP.NET樣板的O / RM是Abp.EntityFramework。你應該把它添加到你的應用程序中。最好是在一個分離的組件實現EntityFramework(DLL)在你的應用和依賴這個組件包。

DbContext

As you know, to work with EntityFramework, you should define a DbContext class for your application. An example DbContext is shown below:

你知道的,和EntityFramework一起工作,你應該定義一個應用程序的DbContext類。例DbContext如下所示:

public class SimpleTaskSystemDbContext : AbpDbContext
{
    public virtual IDbSet<Person> People { get; set; }
    public virtual IDbSet<Task> Tasks { get; set; }

    public SimpleTaskSystemDbContext()
        : base("Default")
    {

    }
    
    public SimpleTaskSystemDbContext(string nameOrConnectionString)
        : base(nameOrConnectionString)
    {

    }

    public SimpleTaskSystemDbContext(DbConnection existingConnection)
        : base(existingConnection, false)
    {

    }

    public SimpleTaskSystemDbContext(DbConnection existingConnection, bool contextOwnsConnection)
        : base(existingConnection, contextOwnsConnection)
    {

    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<Person>().ToTable("StsPeople");
        modelBuilder.Entity<Task>().ToTable("StsTasks").HasOptional(t => t.AssignedPerson);
    }
}

It's a regular DbContext class except following rules:

這是一個常規的DbContext類除以下規則:

  • It's derived from AbpDbContext instead of DbContext.
  • 這是得到abpdbcontext替代 DbContext 。
  • It should have constructors as the sample above (constructor parameter names should also be same). Explanation:
  • 它應該有構造函數作為上面的示例(構造函數形參名稱也應該相同)。解釋:
    • Default consturctor passes "Default" to base bass as the connection string. So, it expects a "Default" named connection string in the web.config/app.config file. This constructor is not used by ABP, but used by EF command line migration tool commands (like update-database).
    • The constructor gets nameOrConnectionString is used by ABP to pass the connection name or string on runtime.
    • The constructor get existingConnection can be used for unit test and not directly used by ABP.
    • The constructor gets existingConnection and contextOwnsConnection is used by ABP on single database multiple dbcontext scenarios to share same connection & transaction () whenDbContextEfTransactionStrategy is used (see Transaction Management section below).
    • 默認構造函數通過“默認”基礎低音的連接字符串。因此,預計“默認”的web.config/app.config文件命名連接字符串。這個構造函數不是由ABP使用的,而是由EF命令行遷移工具命令(如更新數據庫)使用的。
      構造函數獲取nameorconnectionstring采用ABP在運行時通過連接字符串的名稱。
      讓existingconnection構造函數可用於單元測試並不是直接使用ABP。
      構造函數獲取existingconnection和contextownsconnection的ABP單數據庫的多個DbContext場景用來分享相同的連接和交易dbcontexteftransactionstrategy時使用(見交易管理部分)。

EntityFramework can map classes to database tables in a conventional way. You even don't need to make any configuration unless you make some custom stuff. In this example, we mapped entities to different tables. As default, Task entity maps to Tasks table. But we changed it to be StsTasks table. Instead of configuring it with data annotation attributes, I prefered to use fluent configuration. You can choice the way you like.

EF框架可以類映射到數據庫表中的一個常規的方式。你甚至不需要做任何配置,除非你做一些定制的東西。在本例中,我們將實體映射到不同的表中。默認情況下,任務實體映射到任務表。但我們把它換成ststasks表。我不喜歡使用數據注釋屬性來配置它,而是傾向於使用流暢的配置。你可以選擇你喜歡的方式。

Repositories(倉庫)

Repositories are used to abstract data access from higher layers. See repository documentation for more. 

存儲庫用於從高層抽象數據訪問。更多信息請參見庫文檔。

Default Repositories

Abp.EntityFramework implements default repositories for all entities defined in your DbContext. You don't have to create repository classes to use predefined repository methods. Example:

abp.entityframework實現在你定義的所有實體的默認庫DbContext。您不必創建存儲庫類以使用預定義的存儲庫方法。例子:

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 contructor-injects IRepository<Person> and uses the Insert method. In this way, you can easily inject IRepository<TEntity> (or IRepository<TEntity, TPrimaryKey>) and use predefined methods.

personappservice構造函數注入IRepository <person>采用插入法。這樣,你可以很容易地注入IRepository < tentity >(或< tentity IRepository,tprimarykey >),使用預定義的方法。

Custom Repositories

If standard repository methods are not sufficient, you can create custom repository classes for your entities.

如果標准存儲庫方法還不夠,您可以為實體創建自定義存儲庫類。

Application Specific Base Repository Class

ASP.NET Boilerplate provides a base class EfRepositoryBase to implement repositories easily. To implement IRepository interface, you can just derive your repository from this class. But it's better to create your own base class that extens EfRepositoryBase. Thus, you can add shared/common methods to your repositories or override existing methods easily. An example base class all for repositories of a SimpleTaskSystem application:

ASP.NET的模板提供了一個基類庫efrepositorybase實現容易。實施IRepository接口,你可以從這個類派生你的庫。但它更好地創建自己的基地班extens EfRepositoryBase。因此,您可以將共享/公共方法添加到存儲庫中,或者輕松地覆蓋現有的方法。例基類的所有simpletasksystem應用庫:

//Base class for all repositories in my application
public class SimpleTaskSystemRepositoryBase<TEntity, TPrimaryKey> : EfRepositoryBase<SimpleTaskSystemDbContext, TEntity, TPrimaryKey>
    where TEntity : class, IEntity<TPrimaryKey>
{
    public SimpleTaskSystemRepositoryBase(IDbContextProvider<SimpleTaskSystemDbContext> dbContextProvider)
        : base(dbContextProvider)
    {
    }

    //add common methods for all repositories
}

//A shortcut for entities those have integer Id
public class SimpleTaskSystemRepositoryBase<TEntity> : SimpleTaskSystemRepositoryBase<TEntity, int>
    where TEntity : class, IEntity<int>
{
    public SimpleTaskSystemRepositoryBase(IDbContextProvider<SimpleTaskSystemDbContext> dbContextProvider)
        : base(dbContextProvider)
    {
    }

    //do not add any method here, add to the class above (because this class inherits it)
}

Notice that we're inheriting from EfRepositoryBase<SimpleTaskSystemDbContext, TEntity, TPrimaryKey>. This declares to ASP.NET Boilerplate to use SimpleTaskSystemDbContext in our repositories.

注意,我們從efrepositorybase < simpletasksystemdbcontext,TEntity繼承,tprimarykey >。這是ASP.NET的樣板在我們的庫使用simpletasksystemdbcontext。

By default, all repositories for your given DbContext (SimpleTaskSystemDbContext in this example) is implemented using EfRepositoryBase. You can replace it to your own repository base repository class by addingAutoRepositoryTypes attribute to your DbContext as shown below:

默認情況下,你指定的DbContext所有倉庫(simpletasksystemdbcontext這個例子)是用efrepositorybase。你可以換到你自己的庫庫類的屬性你addingautorepositorytypes DbContext如下所示:

[AutoRepositoryTypes(
    typeof(IRepository<>),
    typeof(IRepository<,>),
    typeof(SimpleTaskSystemEfRepositoryBase<>),
    typeof(SimpleTaskSystemEfRepositoryBase<,>)
)]
public class SimpleTaskSystemDbContext : AbpDbContext
{
    ...
}
Custom Repository Example

To implement a custom repository, just derive from your application specific base repository class we created above.

Assume that we have a Task entity that can be assigned to a Person (entity) and a Task has a State (new, assigned, completed... and so on). We may need to write a custom method to get list of Tasks with some conditions and with AssisgnedPerson property pre-fetched (included) in a single database query. See the example code:

要實現自定義存儲庫,只需從上面創建的應用程序特定的基礎存儲庫類中獲得。

 假設我們有一個任務實體可以分配給一個人(實體),任務有一個狀態(新的,分配的,完成的)…等等)。我們需要寫一個獲得有條件的任務列表的自定義方法和屬性assisgnedperson預取(包括)在一個單一的數據庫查詢。請參見示例代碼:

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();
    }
}

We first defined ITaskRepository and then implemented it. GetAll() returns IQueryable<Task>, then we can add some Where filters using given parameters. Finally we can call ToList() to get list of Tasks.

You can also use Context object in repository methods to reach to your DbContext and directly use Entity Framework APIs. 

Note: Define the custom repository interface in the domain/core layer, implement it in the EntityFramework project for layered applications. Thus, you can inject the interface from any project without referencing to EF.

我們首先定義itaskrepository然后實現它。getall()返回IQueryable <任務>,然后我們可以添加一些過濾器使用給定的參數。最后,我們可以稱tolist()得到任務列表。

你也可以在庫的方法使用上下文對象到你的DbContext和直接使用實體框架的API。

注:定義域/核心層的自定義庫的接口,實現其在EntityFramework的項目分層中的應用。因此,您可以在不引用EF的情況下從任何項目注入接口。

Repository Best Practices

  • Use default repositories wherever it's possible. You can use default repository even you have a custom repository for an entity (if you will use standard repository methods).
  • Always create repository base class for your application for custom repositories, as defined above.
  • Define interfaces for your custom repositories in domain layer (.Core project in startup template), custom repository classes in .EntityFramework project if you want to abstract EF from your domain/application.
  • 在可能的地方使用默認存儲庫。您可以使用默認存儲庫,即使您有實體的自定義存儲庫(如果您使用標准存儲庫方法)。
    始終為您的自定義存儲庫應用程序創建存儲庫基類,如上所述。
    定義自定義庫在領域層的接口(在啟動模板核心項目),自定義庫類的。如果你想從你的摘要EF域/應用項目EntityFramework。

Transaction Management(事務管理)

ASP.NET Boilerplate has a built-in unit of work system to manage database connection and transactions. Entity framework has different transaction management approaches. ASP.NET Boilerplate uses ambient TransactionScope approach by default, but also has a built-in implementation for DbContext transaction API. If you want to switch to DbContext transaction API, you can configure it in PreInitialize method of your module like that:

ASP.NET的模板有一個內置的工作單元的系統來管理數據庫連接和交易。實體框架有不同的事務管理方法。ASP.NET樣板使用環境事務處理方法在默認情況下,但也有一個內置的DbContext API實現交易。如果你想切換到DbContext事務API,你可以配置它在你喜歡的方法分發模塊:

Configuration.ReplaceService<IEfTransactionStrategy, DbContextEfTransactionStrategy>(DependencyLifeStyle.Transient);

Remember to add "using Abp.Configuration.Startup;" to your code file to be able to use ReplaceService generic extension method.

In addition, your DbContext should have constructors as described in DbContext section of this document.

記得添加“using Abp.Configuration.Startup;“你的代碼文件,可以使用replaceservice通用的擴展方法。

此外,你應該在DbContext構造函數DbContext部分描述本文件。

Data Stores(數據存儲

Since ASP.NET Boilerplate has built-in integration with EntityFramework, it can work with data stores EntityFramework supports. Our free startup templates are designed to work with Sql Server but you can modify them to work with a different data store.

For example, if you want to work with MySql, please refer to this document

自從ASP.NET樣板與EntityFramework有內置的集成,它可以與數據存儲EntityFramework支持工作。我們的免費啟動模板設計為與SQL Server一起工作,但您可以修改它們以與不同的數據存儲一起工作。

例如,如果您想使用mysql,請參閱此文檔


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM