EFCore CodeFirst模型迁移生成数据库备注(mysql)

重写Mysql下sql脚本生成器

using Framework.NetCore.Extensions;
using Framework.NetCore.Models;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Migrations.Operations;
using Pomelo.EntityFrameworkCore.MySql.Infrastructure.Internal;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;

namespace Framework.NetCore.EfDbContext
{

    public class MyMigrationsSqlGenerator : MySqlMigrationsSqlGenerator
    {
        public MyMigrationsSqlGenerator(
            MigrationsSqlGeneratorDependencies dependencies,
            IMigrationsAnnotationProvider migrationsAnnotations,
            IMySqlOptions mySqlOptions)
            : base(dependencies, migrationsAnnotations, mySqlOptions)
        {
        }

        protected override void Generate(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
        {
            base.Generate(operation, model, builder);

            if (operation is CreateTableOperation || operation is AlterTableOperation)
                CreateTableComment(operation, model, builder);

            if (operation is AddColumnOperation || operation is AlterColumnOperation)
                CreateColumnComment(operation, model, builder);
        }

        /// <summary>
        /// Create table comment.
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="builder"></param>
        private void CreateTableComment(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
        {
            string tableName = string.Empty;
            string description = string.Empty;
            if (operation is AlterTableOperation)
            {
                var t = operation as AlterColumnOperation;
                tableName = (operation as AlterTableOperation).Name;
            }

            if (operation is CreateTableOperation)
            {
                var t = operation as CreateTableOperation;
                var addColumnsOperation = t.Columns;
                tableName = (operation as CreateTableOperation).Name;

                foreach (var item in addColumnsOperation)
                {
                    CreateColumnComment(item, model, builder);
                }
            }
            description = DbDescriptionHelper.GetDescription(tableName);

            if (tableName.IsNullOrWhiteSpace())
                throw new Exception("Create table comment error.");

            var sqlHelper = Dependencies.SqlGenerationHelper;
            builder
            .Append("ALTER TABLE ")
            .Append(sqlHelper.DelimitIdentifier(tableName).ToLower())
            .Append(" COMMENT ")
            .Append("'")
            .Append(description)
            .Append("'")
            .AppendLine(sqlHelper.StatementTerminator)
            .EndCommand();

        }

        /// <summary>
        /// Create column comment.
        /// </summary>
        /// <param name="operation"></param>
        /// <param name="builder"></param>
        private void CreateColumnComment(MigrationOperation operation, IModel model, MigrationCommandListBuilder builder)
        {
            //alter table a1log modify column UUID VARCHAR(26) comment '修改后的字段注释';
            string tableName = string.Empty;
            string columnName = string.Empty;
            string columnType = string.Empty;
            string description = string.Empty;
            if (operation is AlterColumnOperation)
            {
                var t = (operation as AlterColumnOperation);
                tableName = t.Table;
                columnName = t.Name;
                columnType = GetColumnType(t.Schema, t.Table, t.Name, t.ClrType, t.IsUnicode, t.MaxLength, t.IsFixedLength, t.IsRowVersion, model);
            }

            if (operation is AddColumnOperation)
            {
                var t = (operation as AddColumnOperation);
                tableName = t.Table;
                columnName = t.Name;
                columnType = GetColumnType(t.Schema, t.Table, t.Name, t.ClrType, t.IsUnicode, t.MaxLength, t.IsFixedLength, t.IsRowVersion, model);
                description = DbDescriptionHelper.GetDescription(tableName, columnName);
            }

            if (columnName.IsNullOrWhiteSpace() || tableName.IsNullOrWhiteSpace() || columnType.IsNullOrWhiteSpace())
                throw new Exception("Create columnt comment error." + columnName + "/" + tableName + "/" + columnType);

            var sqlHelper = Dependencies.SqlGenerationHelper;
            builder
            .Append("ALTER TABLE ")
            .Append(sqlHelper.DelimitIdentifier(tableName).ToLower())
            .Append(" MODIFY COLUMN ")
            .Append(columnName)
            .Append(" ")
            .Append(columnType)
            .Append(" COMMENT ")
            .Append("'")
            .Append(description)
            .Append("'")
            .AppendLine(sqlHelper.StatementTerminator)
            .EndCommand();

        }
    }

    public class DbDescriptionHelper
    {
        public static string b { get; set; } = "Framework.Website.Models";
        public static string c { get; set; } = @"C:\Users\fxy75\Downloads\pos3.0\Framework.Website.Models";

        public static List<DbDescription> list { get; set; }

        public static string GetDescription(string table, string column = "")
        {
            if (list == null || list.Count() == 0)
            {
                list = GetDescription();
            }

            if (!string.IsNullOrWhiteSpace(table))
            {
                if (string.IsNullOrWhiteSpace(column))
                {
                    var x = list.FirstOrDefault(p => p.Name == table);
                    if (x != null)
                        return x.Description;
                    return string.Empty;
                }
                else
                {
                    var x = list.FirstOrDefault(p => p.Name == table);
                    if (x != null)
                    {
                        var y = x.Column;
                        if (y.IsNotNull())
                        {
                            var z = y.FirstOrDefault(p => p.Name == column);
                            if (z != null)
                                return z.Description;
                        }
                    }
                    return string.Empty;
                }
            }
            else
                return string.Empty;
        }

        public static List<DbDescription> GetDescription()
        {
            var d = new List<DbDescription>();

            var e = Assembly.Load(b);
            var f = e?.GetTypes();
            var g = f?
                .Where(t => t.IsClass
                && !t.IsGenericType
                && !t.IsAbstract
                && t.GetInterfaces().Any(m => m.GetGenericTypeDefinition() == typeof(IBaseModel<>))
                ).ToList();

            foreach (var h in g)
            {
                var i = new DbDescription();

                var j = c + "\\" + h.Name + ".cs";
                var k = File.ReadAllText(j);
                k = k.Substring(k.IndexOf("{") + 1, k.LastIndexOf("}") - k.IndexOf("{") - 1).Replace("\n", "");

                var l = k.Substring(k.IndexOf(" {") + 2, k.LastIndexOf(" }") - k.IndexOf(" {") - 1).Replace("\n", "");
                string[] slipt = { "}\r" };
                var m = l.Split(slipt, StringSplitOptions.None).ToList();

                var n = new List<DbDescription>();
                foreach (var o in m)
                {
                    var p = o.Replace("///", "");

                    var q = p.IndexOf("<summary>");
                    var r = p.LastIndexOf("</summary>");

                    var s = p.IndexOf("public");
                    var t = p.IndexOf("{");

                    var u = (q > 0 && r > 0) ? p.Substring(q + 9, r - q - 10).Replace("\r", "").Replace(" ", "") : "";
                    var v = (s > 0 && t > 0) ? p.Substring(s, t - s).Split(' ')[2] : "";

                    n.Add(new DbDescription()
                    {
                        Description = u,
                        Name = v
                    });
                }

                var w = k.Substring(0, k.IndexOf("{\r") - 1);
                w = w.Replace("///", "");

                var x = w.IndexOf("<summary>");
                var y = w.LastIndexOf("</summary>");
                var z = (x > 0 && y > 0) ? w.Substring(x + 9, y - x - 10).Replace("\r", "").Replace(" ", "") : "";

                d.Add(new DbDescription()
                {
                    Name = h.Name,
                    Description = z,
                    Column = n
                });
            }
            return d;
        }
    }

    public class DbDescription
    {
        public string Name { get; set; }
        public string Description { get; set; }
        public List<DbDescription> Column { get; set; }
    }
}

EFCore DbContext中替换IMigrationsSqlGenerator

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder
                .UseMySql(_option.ConnectionString)
                .ReplaceService<IMigrationsSqlGenerator, MyMigrationsSqlGenerator>();

            base.OnConfiguring(optionsBuilder);
        }

原文地址:https://www.cnblogs.com/fuxuyang/p/10835904.html

时间: 2024-11-03 17:44:20

EFCore CodeFirst模型迁移生成数据库备注(mysql)的相关文章

Entityframework Codefirst模式自动生成数据库方式

EF在codefirst模式下能自动生成数据库,那它是如何生成的呢,默认情况下如何生成的呢?先来看看用来生成数据库的DbContext类吧 1 protected DbContext(); 2 protected DbContext(DbCompiledModel model); 3 public DbContext(string nameOrConnectionString); 4 public DbContext(DbConnection existingConnection, bool c

EF架构~codeFirst从初始化到数据库迁移

一些介绍 CodeFirst是EntityFrameworks的一种开发模式,即代码优先,它以业务代码为主,通过代码来生成数据库,并且加上migration的强大数据表比对功能来生成数据库版本,让程序开发人员不用维护数据库的变更,而直接维护migration即可,在它里面有你当前版本和过去历史版本的所有变更记录! (1)通过EF-CodeFirst自己帮我们建立了数据库,初始化的数据表 第一次建立数据模型,运行程序,自动建立数据库和数据表,并执行对应的初始化工作 数据模型 数据初始化 EF在Li

django之模型类、迁移和数据库表之间的关系

环境配置:ubuntu 16.04,Django 1.8.2,MySQL-python 1.2.5 目的是为了了解模型类的定义和其对应数据库里面表的关系 实测发现: 关于模型类和数据库里面的表关系,模型类里面定义的类属性是为了生成数据库里面的表结构使用的,类似mysql里面创建一个表. 一个模型类,对应着数据库里面的一个表. 一个类属性,对应着数据库表里面的一个字段 一个类属性的类型(如charfield),对应着数据库里面字段类型. 进入python manage.py shell运行的pyt

Django:模型(model)和数据库(mysql)(一)

以一个栗子尝试来记录: 两个表存储在数据库中,BookInfo表示书,HeroInfo表示人物.一本书中有多个人物 在MySQL中新建一个数据库Django1,不用创建表,用Django模型来配置数据库 1.数据库ER图 2.数据库配置 在settings.py中进行数据库的配置. 留意:django默认连接的是sqlite3数据库.我们需要修改成MySQL django1/settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.b

PowerDesigner生成数据库表和逆向生成表结构(MySQL数据库)

一.Download Connector/ODBC下载ODBC驱动,地址:https://dev.mysql.com/downloads/connector/odbc/, 需要注意:PowerDesigner安装的多少位就下载多少位的,一般是32位,建议下载.msi文件直接安装. 二.安装完成后点击powerdesigner的Database--->Configure Connections...--->添加数据源配置,如下图: 三.PDM模型生成数据库sql文件,点击powerdesigne

使用Entity Framework迁移完数据库后,每次修改代码(非模型代码)后都报错。

问题:使用Entity Framework迁移完数据库后,每次修改代码(非模型代码)后都报错: 支持“XXXDbContext”上下文的模型已在数据库创建后发生更改.请考虑使用 Code First 迁移更新数据库(http://go.microsoft.com/fwlink/?LinkId=238269). 这时如果执行 Add-Migration 生成的迁移代码是空的.于是重新Update-Database,结果却是No pending explicit migrations. 不过这时是不

ABP增加记录EFCore 生成数据库脚本日志到新的txt文件

由于EFCore并没直接生成脚本到txt文件,故而自己画了点时间把实现记录下来,方便给大家参考. 0.安装Microsoft.Extensions.Logging.Debug,我这里是2.1.1版本. 1.新建一个EFCoreDatabaseCmdLog在abp的Core层下, using Abp.Dependency; using Castle.Core.Logging; namespace SensorBroker.Log { public static class EFCoreDataba

记录一次EFCore CodeFirst迁移实践,解决多个项目表结构同步更新问题

背景: 项目中使用的是EFCore2.1的DbFirst模式,但由于多个项目使用了相同的基础框架,每次同步更新数据库结构很麻烦,因此同时使用了CodeFirst来进行迁移实现同步.其中,项目A的数据库版本为最新,项目B为旧,现要自动将B项目的数据库结构和A项目保持一致. 过程介绍: 首先要知道,CodeFirst中的Update-database可以实现数据库的创建和结构更新,但结构更新必须有前一次的迁移记录,否则无法自动比对变化,也就无法进行准确的升级更新. 项目B正是这样,从未进行过迁移,因

EntityFramework 6 SQLite CodeFirst 生成数据库

预计 EntityFramework7(EF7) 将完美的支持 SQLite 在EF7正式版完成前, 通过 SQLite.CodeFirst 可以让我们生成数据库 原文已经无法打开,此链接为转载: http://www.tuicool.com/articles/ZjMbUzy%20