2.實現一個簡單的任務
創建實體
把實體類寫在Core項目中,因為實體是領域層的一部分。
一個簡單的應用場景:創建一些任務(Assignment)並分配給人。 我們需要Assignment和Person這兩個實體。
public class Assignment : Entity<long> { //外鍵 [ForeignKey("AssignedPersonId")] public virtual Person AssignedPerson { get; set; } //外鍵 public virtual int? AssignedPersonId { getView Code; set; } public virtual string Description { get; set; } [Required] [Column(TypeName ="date")] //描述 public virtual DateTime CreationTime { get; set; } //狀態 public virtual bool State { get; set; } //默認值 public Assignment() { CreationTime= DateTime.Now; State = true; } }
public class Person:Entity { [Required] [StringLength(50)] public virtual string Name { get; set; } }View Code
Assignment實體有幾個屬性:描述(Description)、創建時間(CreationTime)、任務狀態(State),還有可選的導航屬性(AssignedPerson)來引用Person。
在ABP框架中,有一個Entity基類,它有一個Id屬性。因為Assignment類繼承自Entity<long>,所以它有一個long類型的Id。Person類有一個int類型的Id,因為int類型是Entity基類Id的默認類型,沒有特別指定類型時,實體的Id就是int類型。
創建DbContext
使用EntityFramework需要先定義DbContext類,ABP的模板已經創建了DbContext文件,我們只需要把Assignment和Person類添加到IDbSet,請看代碼:
public class AbpProjectDbContext : AbpZeroDbContext<Tenant, Role, User> { //TODO: Define an IDbSet for your Entities... /* NOTE: * Setting "Default" to base class helps us when working migration commands on Package Manager Console. * But it may cause problems when working Migrate.exe of EF. If you will apply migrations on command line, do not * pass connection string name to base classes. ABP works either way. */ //添加IDbSet public virtual IDbSet<Assignment> Assignments { get; set; } public virtual IDbSet<Person> Person { get; set; } public AbpProjectDbContext() : base("Default") { } /* NOTE: * This constructor is used by ABP to pass connection string defined in AbpProjectDataModule.PreInitialize. * Notice that, actually you will not directly create an instance of AbpProjectDbContext since ABP automatically handles it. */ public AbpProjectDbContext(string nameOrConnectionString) : base(nameOrConnectionString) { } //This constructor is used in tests public AbpProjectDbContext(DbConnection existingConnection) : base(existingConnection, false) { } public AbpProjectDbContext(DbConnection existingConnection, bool contextOwnsConnection) : base(existingConnection, contextOwnsConnection) { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); } }View Code
在VS2013底部的“程序包管理器控制臺”窗口中,選擇默認項目並執行命令“Add-Migration InitialCreate”
會在Migrations文件夾下生成一個xxxx-InitialCreate.cs文件,內容如下:
然後繼續在“程序包管理器控制臺”執行“Update-Database”,會自動在數據庫創建相應的數據表:
重新生成表
1.刪除Migrations文件夾下生成的xxxx-InitialCreate.cs文件
2.刪除數據庫中的表__MigrationHistory中剛生成的記錄
3.刪除生成的表
4.重新執行以上兩步步驟即可
定義倉儲接口
通過倉儲模式,可以更好把業務代碼與數據庫操作代碼更好的分離,可以針對不同的數據庫有不同的實現類,而業務代碼不需要修改。
定義倉儲接口的代碼寫到Core項目中,因為倉儲接口是領域層的一部分。
我們先定義Assignment的倉儲接口:
/// <summary> /// 定義倉儲接口 /// </summary> public interface IAssignmentRepository: IRepository<Assignment,long> { List<Assignment> GetAllWithPeople(int? assignedPersonId, bool? state); }
它繼承自ABP框架中的IRepository泛型接口。
在IRepository中已經定義了常用的增刪改查方法:
所以IAssignmentRepository默認就有了上面那些方法。可以再加上它獨有的方法GetAllWithPeople(...)。
不需要為Person類創建一個倉儲類,因為默認的方法已經夠用了。ABP提供了一種註入通用倉儲的方式,將在後面“創建應用服務”一節的AssignmentAppService類中看到。
實現倉儲類
我們將在EntityFramework項目中實現上面定義的IAssignmentRepository倉儲接口。
EntityFramework項目下的文件夾Repositories下已經定義了一個倉儲基類(在):AbpProjectRepositoryBase(這是一種比較好的實踐,因為以後可以在這個基類中添加通用的方法)。
public class AssignmentRepository : AbpProjectRepositoryBase<Assignment, long>, IAssignmentRepository { public AssignmentRepository(IDbContextProvider<AbpProjectDbContext> dbContextProvider) : base(dbContextProvider) { } public List<Assignment> GetAllWithPeople(int? assignedPersonId, bool? state) { //在倉儲方法中,不用處理數據庫連接、DbContext和數據事務,ABP框架會自動處理。 var query = GetAll(); //GetAll() 返回一個 IQueryable<T>接口類型 //添加一些Where條件 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(); } }View Code
2.實現一個簡單的任務