2.实现一个简单的任务

Posted 小魔女srn

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2.实现一个简单的任务相关的知识,希望对你有一定的参考价值。

创建实体

把实体类写在Core项目中,因为实体是领域层的一部分。

一个简单的应用场景:创建一些任务(Assignment)并分配给人。 我们需要AssignmentPerson这两个实体。

 public class Assignment : Entity<long>
    {
        //外键
        [ForeignKey("AssignedPersonId")]
        public virtual Person AssignedPerson { get; set; }
        //外键
        public virtual int? AssignedPersonId { get; 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;
        }
    }
View Code
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文件,我们只需要把AssignmentPerson类添加到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

 AssignmentRepository继承自AbpProjectRepositoryBase并且实现了上面定义的IAssignmentRepository接口。

以上是关于2.实现一个简单的任务的主要内容,如果未能解决你的问题,请参考以下文章

VS2015 代码片段整理

Leetcode:Task Scheduler分析和实现

有没有办法将2个非常相似的代码片段组合成一个函数并重复?

导航抽屉异步任务

需要示例代码片段帮助

如何有条件地将 C 代码片段编译到我的 Perl 模块?