MySql生成.Net中Model类的存储过程

介绍了一个MySQL存储过程,用于自动生成Entity Framework (EF) 的Model类,并附带字段注释,提高了开发效率。

最近用Mysql,花时间写了一个过程用来生成EF的model类,有注释,挺方便,用EF类Entity自动生成的没有字段注释。


要用到的函数:

DELIMITER $$
DROP FUNCTION IF EXISTS `fun_GetCSTypeFromDbType`$$
CREATE FUNCTION `fun_GetCSTypeFromDbType`(#本函数不需要在线上执行
dbtype VARCHAR(50)
)
    RETURNS VARCHAR(50)
    
    BEGIN
	DECLARE ret VARCHAR(50);
	IF dbtype='nvarchar' OR dbtype='varchar' OR dbtype='text' 
		THEN SET ret='string';
	ELSEIF dbtype='datetime' OR dbtype='date' 
		THEN SET ret='DateTime';
	ELSEIF dbtype='bit' 
		THEN SET ret='bool';
	ELSEIF dbtype='bigint' 
		THEN SET ret='long';
	ELSE SET ret=dbtype;
	END IF;
	RETURN ret;
    END$$

DELIMITER ;
/*
select fun_GetCSTypeFromDbType('bit');
*/



DELIMITER $$
DROP PROCEDURE IF EXISTS `P_GenerateModel`$$
CREATE PROCEDURE `P_GenerateModel`(##本存储过程不会在程序中调用,不需在线上执行,调用了函数 fun_GetCSTypeFromDbType 如果在其他库执行要注意,author:pukuimin
tableSchema VARCHAR(50),-- 用到的数据库
tableName VARCHAR(50) #要生成的类名
)

BEGIN
DECLARE count1_1 INT;
DECLARE retString VARCHAR(8000);
DECLARE table_name1,column_Name1,is_nullable1,data_type1,character_maximum_length1,column_comment1,Column_Key1 VARCHAR(100);
DECLARE REFERENCED_TABLE_NAME1,REFERENCED_COLUMN_NAME1 VARCHAR(100);
DECLARE pri_Column_Name,pri_data_type VARCHAR(100);
-- 需要定义接收游标数据的变量 
-- 遍历数据结束标志
DECLARE done INT DEFAULT 0;
DECLARE cur CURSOR FOR SELECT table_name,column_Name,is_nullable,data_type,character_maximum_length,column_comment,Column_Key FROM information_schema.COLUMNS WHERE table_schema=tableSchema AND table_name = tableName;

DECLARE cur2 CURSOR FOR SELECT table_name,column_name,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema=tableSchema AND table_name = tableName;

-- 将结束标志绑定到游标
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
SET retString = ''; #初始化为空串
SET retString=CONCAT(retString,'namespace YCF.Stock.Core.Entities
{
    using Abp.Domain.Entities;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using YCF.Stock.Core.Enum;
');
SET retString=CONCAT(retString,'    [Table("',tableName,'")]',CHAR(10));


SELECT column_Name,data_type INTO pri_Column_Name, pri_data_type FROM information_schema.COLUMNS WHERE table_schema=tableSchema AND table_name = tableName AND Column_Key='PRI' LIMIT 1;
SET retString=CONCAT(retString,'    public partial class ',tableName,' : Entity<',fun_GetCSTypeFromDbType(pri_data_type),'>',CHAR(10));
SET retString=CONCAT(retString,'    {',CHAR(10));
#set retString=CONCAT(retString,'//    priName:',pri_Column_Name,',priType:',pri_data_type,char(10));

-- 打开游标
OPEN cur;
  
-- 开始循环
read_loop: LOOP
    -- 提取游标里的数据,这里只有一个,多个的话也一样;
    FETCH cur INTO table_name1,column_Name1,is_nullable1,data_type1,character_maximum_length1,column_comment1,Column_Key1;
    -- 声明结束的时候
    IF done=1 THEN
      LEAVE read_loop;
    END IF;
    -- 这里做你想做的循环的事件
    #set retString=CONCAT(retString,'',CHAR(10));
    SET retString=CONCAT(retString,'
        /// <summary>
        /// ',column_comment1,'
        /// </summary>
');
IF data_type1='varchar' OR data_type1='varchar' THEN 
	SET retString=CONCAT(retString,'        [StringLength(',character_maximum_length1,')]
        [MaxLength(',character_maximum_length1,')]',CHAR(10));
ELSEIF data_type1='date' OR data_type1='bit' THEN 
	SET retString=CONCAT(retString,'        [Column(TypeName = "',data_type1,'")]',CHAR(10));
END IF;
IF Column_Key1='PRI' THEN 
	SET retString=CONCAT(retString,'        [Column("',column_Name1,'")]',CHAR(10),'        public override ',fun_GetCSTypeFromDbType(data_type1),' Id { get; set; }',CHAR(10));
ELSE
	SET retString=CONCAT(retString,'        public ',fun_GetCSTypeFromDbType(data_type1),CASE WHEN is_nullable1 ='YES' THEN '?' ELSE '' END,' ',column_Name1,' { get; set; }',CHAR(10));
END IF;


END LOOP;
  -- 关闭游标
CLOSE cur;
SET done=0;#重新把done标识为0,开始第二个游标
SET retString=CONCAT(retString,'/*',CHAR(10));
  -- 打开游标2
OPEN cur2;
-- 开始循环
  read_loop2: LOOP
      -- 提取游标里的数据,这里只有一个,多个的话也一样;
    FETCH cur2 INTO table_name1,column_Name1,REFERENCED_TABLE_NAME1,REFERENCED_COLUMN_NAME1;
    -- 声明结束的时候
    IF done=1 THEN
      LEAVE read_loop2;
    END IF;
    -- 这里做你想做的循环的事件
    #set retString=CONCAT(retString,'',CHAR(10));
    IF REFERENCED_TABLE_NAME1 IS NOT NULL THEN 
	SET retString=CONCAT(retString,'        public virtual ',REFERENCED_TABLE_NAME1,' ',REFERENCED_TABLE_NAME1,' { get; set; }',CHAR(10));
    END IF;
  END LOOP;
    -- 关闭游标2
CLOSE cur2;
SET retString=CONCAT(retString,'/*',CHAR(10));
  SET retString=CONCAT(retString,'#warning 因数据库表名全部自动小写,请手动调整导航属性 public virtual XXX XXX { get; set; }',CHAR(10));
SET retString=CONCAT(retString,'
    }
}',CHAR(10));
SELECT retString;
END$$

DELIMITER ;
/*
call P_GenerateModel('MyDB','ItemContractStock');
*/


调用生成,复制到Model.cs中就行了。方便快捷。


不同的项目,可能要根据不同的类名、命名空间等等把固定的部分修改一下,其他的都一样,就是字段、类型和注释的生成。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值