大红鹰葡京会于.NET Core类库中应用EF Core迁移数据库及SQL ServerSlickflow.NET 开源工作流引擎基础介绍(九) — .NET Core2.0 版本实现介绍。

前言

假使大家刚刚动EntityFramework
Core作为ORM框架的话,想必都见面遇上数据库迁移的部分问题。

胚胎我是当ASP.NET
Core的Web项目遭到进行的,但新兴发觉在此处并无是雅客观,一些有关数据库的迁,比如新增表,字段,修改字段类型等等,不应当同最好上层的Web项目所涉及,数据的搬迁文件放到这里呢觉得有点多余,有硌乱乱的感觉到,所以才想在单身出来由专门的档次进展管理会比较好,也比清晰!

顾目标框架选择的是.NET Core 2.0要是休是.NET
Standard 2.0。

前言:.NET Core 是.NET
Framework的新一代表版本,是微软开支之首先独跨平台
(Windows、Mac
OSX、Linux)
的应用程序开发框架(Application
Framework),未来吗用会见支撑 FreeBSD 与 Alpine 平台。.Net
Core也是微软在同等开始提高时虽开源的软件平台,其开发目标是过平台的 .NET
平台。

0、前期准备

a)、表实体定义,这个是在.NET
Standard 2.0的类库中存放的。

    /// <summary>
    /// 系统应用的用户实体
    /// </summary>
    public class ApplicationUser : BaseModel
    {
        /// <summary>
        /// 用户名
        /// </summary>
        public string UserName { get; set; }

        /// <summary>
        /// 密码
        /// </summary>
        public string Password { get; set; }

        /// <summary>
        /// 邮件地址
        /// </summary>
        public string Email { get; set; }
    }

b)、新建一个.NET Core
2.0之类库,并定义好我们所要运的数据库上下文,很简单,接下开始我们的正文

    /// <summary>
    /// 系统上下文
    /// </summary>
    public class LightContext : DbContext
    {
        public LightContext(DbContextOptions<LightContext> options) : base(options)
        {
        }

        /// <summary>
        /// 系统应用用户
        /// </summary>
        public DbSet<ApplicationUser> ApplicationUser { get; set; }

        /// <summary>
        /// 角色表
        /// </summary>
        public DbSet<Role> Role { get; set; }
    }

.NET Core 平台的开销优势 :

1、问题汇集

首先使保管仓储类库中已引入以下简单独Nuget包,没有底说话请以包管理器进行设置。不建议直接引入原包:Microsoft.AspNetCore.All,按需要引入即可

Install-Package Microsoft.EntityFrameworkCore.SqlServer

Install-Package Microsoft.EntityFrameworkCore.Tools

a)打开CMD,然后切换到类库所在路径下,执行以下命令。不过你吗得以应用程序包管理器控制台(PMC)进行搬迁,但是会生半点变化,部分令见下表:

迁移命令描述 CMD命令 PMC命令
创建迁移:migrationname为迁移名称 dotnet ef migrations add migrationname add-migration migrationname
移除迁移(删除最近的一次迁移) dotnet ef migrations remove remove-migration
应用最新的迁移(使迁移文件应用到数据库) dotnet ef database update update-database
应用指定的迁移 dotnet ef database update migrationname update-database migrationname
查看迁移列表 dotnet ef migrations list  
查看数据库上下文信息 dotnet ef dbcontext info  
dotnet ef

大红鹰葡京会 1

左提示:

  未找到与命令“dotnet-ef”匹配的可执行文件

缓解智:

  于项目文件Light.Repository.csproj中补充加以下节点

<ItemGroup>
    <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.1" />
</ItemGroup>

还履行方的命,如果起了EF
Core的标志(一头蓄势待发的野马)表示早已成

大红鹰葡京会 2

 b)、执行以下命令进行搬迁

dotnet ef migrations add InitLightDB

大红鹰葡京会 3

左提示:

The specified framework version ‘2.0’ could
not be parsed
The specified framework
‘Microsoft.NETCore.App’, version ‘2.0’ was not found.

  • Check application dependencies and
    target a framework version installed at:
    \
  • Alternatively, install the framework
    version ‘2.0’.

缓解方式:

  在类型文件被上加以下节点:

  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <RuntimeFrameworkVersion>2.0.3</RuntimeFrameworkVersion>
  </PropertyGroup>

c)、重新履行b步骤的一声令下,报错信息如下:

大红鹰葡京会 4

错误提示:

  Unable to create an object of type
‘LightContext’. Add an implementation of
‘IDesignTimeDbContextFactory<LightContext>’ to the project, or see
https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns
supported at design time.

这问题要是在Web项目,并且安排了DbContext的链接字符串的话,是勿会见油然而生是题材的。很强烈是搬迁命令没有找到DbConnectionString导致的,接下我们仍提示,实现一个IDesignTimeDbContextFactory<LightContext>试试

釜底抽薪智:

  创建一个及DbContext同一目录下的DesignTimeDbContextFactory文件,然后实现接口中之章程CreateDbContext,并配置ConnectionString

   public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<LightContext>
    {
        public LightContext CreateDbContext(string[] args)
        {
            var builder = new DbContextOptionsBuilder<LightContext>();
            builder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Integrated Security=true;Initial Catalog=Light;");
            return new LightContext(builder.Options);
        }
    }

 再次实施迁移命令,终于成功了。

大红鹰葡京会 5

马到成功唤醒:

  Done. To undo this action, use ‘ef
migrations remove’

与此同时类库下面会生成Migrations文件夹和相关的搬文件

大红鹰葡京会 6

  1. 支持还是可移转 (port) 到更多的操作系统平台及芯片架构
    (也便是鹏程档会过出 x86 平台)。
  2. 有显著之习性与大可靠度。
  3. 开发人员能便捷与直觉的收获 .NET Core 开发环境。
  4. 当直觉和持有生产力的情状下修建应用程序,使用文件,示例与 NuGet 组件。

2、小试迁移命令

a)、使用以下命令下迁移,生成数据库与阐发

dotnet ef database update

大红鹰葡京会 7

通过VS的SQL
Server资源管理器查看转数据库的结构,其中__EFMigrationsHistory也每次迁移的记录表

大红鹰葡京会 8

b)、因为string类型的字段迁移至数据库后的数据类型为nvarchar(max)并且是只是空类型的,下面我们就算应用Fluent
API对ApplicationUser表字段展开布置,同样你啊得采用性能注解的主意开展配备,因为自身自己非喜欢“污染”表实体

    public static void ConfigApplicationUser(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<ApplicationUser>(m =>
            {
                m.Property(t => t.Email)
                        .HasMaxLength(50);

                m.Property(t => t.UserName)
                        .IsRequired()
                        .HasMaxLength(50);

                m.Property(t => t.Password)
                        .IsRequired()
                        .HasMaxLength(20);
            });
        }

接下来同使用方面的个别长命令还搬并更新数据库结构

大红鹰葡京会 9

观测数据库表结构已经更新

大红鹰葡京会 10

 同理添加字段,删除字段都是一律的迁操作,还是特别便宜的

上述文字引用来源:https://zh.wikipedia.org/wiki/.NET\_Core

3、扩展

a)、为了好演示,其实上面在类库中实践迁移时的数据库连接字符串是描写好的,那么最好好之艺术是应去读取Web项目下一度布置好之连年,这样便会担保上下的一致性,不用再行去为EF的迁而独维护一个结余的数据库连接配置。改造也坏粗略,即通过Configuration组件读取appsettings.json的ConnectionStrings节点,改造后是这样子的:

    public class DesignTimeDbContextFactory : IDesignTimeDbContextFactory<LightContext>
    {
        public LightContext CreateDbContext(string[] args)
        {
            Directory.SetCurrentDirectory("..");//设置当前路径为当前解决方案的路径
            string appSettingBasePath = Directory.GetCurrentDirectory() + "/Light.AuthorityApi";//改成你的appsettings.json所在的项目名称
            var configBuilder = new ConfigurationBuilder()
                .SetBasePath(appSettingBasePath)
                .AddJsonFile("appsettings.json")
                .Build();

            var builder = new DbContextOptionsBuilder<LightContext>();
            //builder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Integrated Security=true;Initial Catalog=Light;");
            builder.UseSqlServer(configBuilder.GetConnectionString("LightConnection"));
            return new LightContext(builder.Options);
        }
    }

小心得分外引入下面这Nuget包:

Install-Package Microsoft.Extensions.Configuration.Json

b)、属性注解[Column(Order = 1)]本着EF
Core来说还从未达标可以调数据库生成字段的逐条,不过我们或可以修改迁移文件之实业性之顺序来上我们想只要之作用。下面是我调之后再也转的发明,是无是圈下与方面的发出什么不同,一图胜万语:

大红鹰葡京会 11

 c)、最后一步,自己动手试试看:创建一个SeedData迁移文件来补充加数据库的启幕数据。:)

1. .NET Core 2.0 迁移指南

4、最后

EF
Core的强大远不止这些,还有更多的利用方式齐正咱失去发现,去追究。每天进步一点点,是项大高兴的政工!

    由于.NET Core跨平台开发以及总体性方面的优势,再加上.NET
Core2.0版的推出,越来越多的客户逐渐迁移至.NET
Core框架进行软件系统的付出。Slickflow引擎组件的.NET
Core版本的推出,也是为化解过平台引擎产品的贯彻。本文大致描述了创建.NET
Core2.0 为对象版本类库,数据看项目与Asp.NET Mvc
Core等档次项目的搭建过程,方便用户快速上手。

1.1 数据看项目

1) IRepository模式实现

   
Repository模式实现通用数据看接口,其利是首先定义来专业的增删改查接口,其次可以满足对接后端不同的多寡处理框架,如Dapper,EF和NHibernate等框架。

/// <summary>
    /// 数据操作类接口
    /// </summary>
    /// <typeparam name="T">数据实体类型</typeparam>
    public interface IRepository<T> where T : class
    {
        DbSet<T> GetDbSet();

        T GetByID(dynamic id);
        T Get(Expression<Func<T, bool>> predicate);
        IQueryable<T> GetAll();

        IQueryable<T> Query(string sql, params object[] parameters);
        IEnumerable<T> Query(Expression<Func<T, bool>> predicate);
        int Count(Expression<Func<T, bool>> predicate = null);


        //insert, update, delete
        T Insert(T entity);
        void Insert(params T[] entities);
        void Insert(IEnumerable<T> entities);
        void Update(T entity);
        void Update(params T[] entities);
        void Update(IEnumerable<T> entities);
        void Delete(dynamic id);
        void Delete(params T[] entities);
        void Delete(IEnumerable<T> entities);
    }

2) UnitOfWork 解决工作

   
引擎内部逻辑处理一般是多表的插入编辑操作,为保持数据事务完整性,需要实现会话事务之参数传递,提供提交和回滚的处理方式。Slickflow.Data.IDbSession用来落实UnitOfWork模式。

    /// <summary>
    /// 数据会话接口
    /// </summary>
    public interface IDbSession : IDisposable
    {
        DbContext DbContext { get; }
        IRepository<T> GetRepository<T>() where T : class;
        int SaveChanges();
        int ExecuteSqlCommand(string sql, params object[] paramters);
    }

   
代码示例:Session作为参数,传入具体接口方法,最终兑现业务的平提交或回滚。

/// <summary>
        ///  运行流程测试
        /// </summary>
        /// <param name="runner">运行者</param>
        /// <returns>执行结果</returns>
        [HttpPost]
        public ResponseResult RunProcessApp([FromBody] WfAppRunner runner)
        {
            using (var session = DbFactory.CreateSession())
            {
                var transaction = session.DbContext.Database.BeginTransaction();
                var wfService = new WorkflowService();
                var result = wfService.RunProcessApp(runner, session);

                if (result.Status == WfExecutedStatus.Success)
                {
                    transaction.Commit();
                    return ResponseResult.Success();
                }
                else
                {
                    transaction.Rollback();
                    return ResponseResult.Error(result.Message);
                }
            }
        }

1.2 Asp.NET Mvc Core项目

1) Mvc和WebAPI路由统一部署

   
通常以.NET项目开支被,Mvc项目用于前端页面展现,WebAPI用于后端接口实现。在类型执行进程中,可以以鲜单种类结合为同样,便于环境布置。

app.UseMvc(route => {
                route.MapRoute(
                    name: "default",
                    template: "{controller=Home}/{action=Index}/{id?}");

                route.MapRoute(
                    name:"defaultApi", 
                    template: "api/{controller}/{action}/{id?}");
            });

2) 数据库连接串配置

  大红鹰葡京会  数据库链接串在appsettings.json文件中开展定义,读取方法如下:

            var dbType = ConfigurationExtensions.GetConnectionString(Configuration, "WfDBConnectionType");
            var sqlConnectionString = ConfigurationExtensions.GetConnectionString(Configuration, "WfDBConnectionString");

            Slickflow.Data.ConnectionString.DbType = dbType;
            Slickflow.Data.ConnectionString.Value = sqlConnectionString;

3) DbContext 数据库类型匹配

   
由于不同类别数据库的数目访问组件不同,所以专门做了接口对承诺相当,传入数据库连接串值。

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (ConnectionString.DbType == DatabaseTypeEnum.SQLSERVER.ToString())
                optionsBuilder.UseSqlServer(ConnectionString.Value);
            else if (ConnectionString.DbType == DatabaseTypeEnum.MYSQL.ToString())
                optionsBuilder.UseMySql(ConnectionString.Value);
            else if (ConnectionString.DbType == DatabaseTypeEnum.ORACLE.ToString())
                optionsBuilder.UseOracle(ConnectionString.Value);
        }

  

2. EF Core对大多数据库生成的支撑

    EF Code
First
凡是出于实体来深成数据库模型,简要过程描述为:首先定义好实体对象,对承诺数据库字段类型,然后执行EF
Migrations的操作命令来生成数据库对象。其中常利用的下令有:

   1) dotnet ef migrations add MyFirstMigraton

   2) dotnet ef migrations update database

   下面就是盖WfProcess表的创造来说明大致的缔造过程。

2.1 MS SQLSERVER数据库

    采用的多寡访问组件默认为:Microsoft.EntityFrameworkCore。

 1) 实体属性标识

 /// <summary>
    /// 流程实体类
    /// </summary>
    [Table("WfProcess")]
    public class ProcessEntity
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Column(Order = 0)]
        public int ID { get; set; }

        [Required]
        [Column(TypeName = "varchar(100)", Order = 1)]
        [MaxLength(100)]
        public string ProcessGUID { get; set; }

        [Required]
        [Column(TypeName = "nvarchar(50)", Order = 2)]
        [MaxLength(50)]
        public string ProcessName { get; set; }

        [Required]
        [Column(TypeName ="nvarchar(20)", Order = 3)]
        [MaxLength(20)]
        public string Version { get; set; }
    }

 2) 默认值赋值

//流程创建
            modelBuilder.Entity<ProcessEntity>(entity =>
            {
                entity.Property(e => e.Version).HasDefaultValue("1");
                entity.Property(e => e.IsUsing).HasDefaultValue(0);
                entity.Property(e => e.StartType).HasDefaultValue(0);
                entity.Property(e => e.EndType).HasDefaultValue(0);
                entity.Property(e => e.CreatedDateTime).HasDefaultValueSql("getdate()");
            });

 3) 生成令执行

dotnet ef migrations add
MyFirstMigration

2.2 MySQL数据库

    采用的数码看组件默认为:Polemo.EntityFrameworkCore.MySQL。

  1) 实体属性标识

    /// <summary>
    /// 流程实体类
    /// </summary>
    [Table("WfProcess")]
    public class ProcessEntity
    {
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Column(Order = 0)]
        public int ID { get; set; }

        [Required]
        [Column(TypeName = "varchar(100)", Order = 1)]
        [MaxLength(100)]
        public string ProcessGUID { get; set; }

        [Required]
        [Column(TypeName = "varchar(50)", Order = 2)]
        [MaxLength(50)]
        public string ProcessName { get; set; }

        [Required]
        [Column(TypeName ="varchar(20)", Order = 3)]
        [MaxLength(20)]
        public string Version { get; set; }
    }

  2) 默认值赋值

            //流程创建
            modelBuilder.Entity<ProcessEntity>(entity =>
            {
                entity.Property(e => e.Version).HasDefaultValue("1");
                entity.Property(e => e.IsUsing).HasDefaultValue(0);
                entity.Property(e => e.StartType).HasDefaultValue(0);
                entity.Property(e => e.EndType).HasDefaultValue(0);
            });

  3) 生成令执行

dotnet ef migrations add
MyFirstMigration

3. Slickflow.WebAPI 高速测试

 3.1 路由模式选定:

    仍然选定传统路由模式,便于接口快速识别和配合。

            app.UseMvc(route => {
                route.MapRoute(
                    name: "defaultApi",
                    template: "api/{controller}/{action}/{id?}");
            });

3.2 数据库链接串读取:

            var dbType = ConfigurationExtensions.GetConnectionString(Configuration, "WfDBConnectionType");
            var sqlConnectionString = ConfigurationExtensions.GetConnectionString(Configuration, "WfDBConnectionString");

            Slickflow.Data.ConnectionString.DbType = dbType;
            Slickflow.Data.ConnectionString.Value = sqlConnectionString;

3.3 测试接口方法

        /// <summary>
        ///  启动流程测试
        /// </summary>
        /// <param name="runner">运行者</param>
        /// <returns>执行结果</returns>
        [HttpPost]
        public ResponseResult StartProcess([FromBody] WfAppRunner runner)
        {
            using (var session = DbFactory.CreateSession())
            {
                var transaction = session.DbContext.Database.BeginTransaction();
                var wfService = new WorkflowService();
                var result = wfService.StartProcess(runner, session);

                if (result.Status == WfExecutedStatus.Success)
                {
                    transaction.Commit();
                    return ResponseResult.Success();
                }
                else
                {
                    transaction.Rollback();
                    return ResponseResult.Error(result.Message);
                }
            }
        }

3.4 RestClient 测试工具

   
 引擎接口测试用RestClient工具,比较方便快捷。通常采取统一之接口方法,将不同类型的流程JSON数据格式作为测试用例来付测试。

大红鹰葡京会 12

4. 总结

     Slickflow 引擎产品之.NET
Core版本实现,用于跨平台利用之种开发同事务集成。而且以数据库的支撑及,采用EF
Core的Code First数据库迁移创建,方便用户支出条件的飞快搭建和布局。

相关文章

admin

网站地图xml地图