.Net初使用MySql数据库生成Model类并与SqlServer简单对比

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 最近的一个项目,在.net中使用MySql数据库,背景是这样的:Sql Server要购买授权,每年100多万,本来公司这么大,这点钱也不算什么,但是领导说能省就省。

最近的一个项目,在.net中使用MySql数据库,背景是这样的:Sql Server要购买授权,每年100多万,本来公司这么大,这点钱也不算什么,但是领导说能省就省。对于技术人员来说,这是个挑战,时间紧,技术上还有未知的风险。想想从实习到现在,四年多的.Net研发了,都是用的Sql Server数据库,这个Mysql还是头一回用……


一、根据数据库生成EF的Model类

//表字段信息model

    public class TableSchemaModel
    {
        /// <summary>
        /// 表名
        /// </summary>
        public string TableName { get; set; }
        /// <summary>
        /// 字段名
        /// </summary>
        public string ColumnName { get; set; }
        /// <summary>
        /// 是否可空:可空-YES,不可空-NO
        /// </summary>
        public string IsNullable { get; set; }
        /// <summary>
        /// 字段数据类型
        /// </summary>
        public string DataType { get; set; }
        /// <summary>
        /// 字符串长度
        /// </summary>
        public int? CharacterMaximumLength { get; set; }
        /// <summary>
        /// 字段描述
        /// </summary>
        public string ColumnComment { get; set; }
        /// <summary>
        /// 键标识:主键-PRI,外键-MUL
        /// </summary>
        public string ColumnKey { get; set; }
    }

    public class TableRefrenceModel
    {
        /// <summary>
        /// 表名
        /// </summary>
        public string TableName { get; set; }
        /// <summary>
        /// 字段名
        /// </summary>
        public string ColumnName { get; set; }
        /// <summary>
        /// 关联的表名
        /// </summary>
        public string ReferencedTableName { get; set; }
        /// <summary>
        /// 关联的表字段名
        /// </summary>
        public string ReferencedColumnName { get; set; }
    }


//具体的处理方法,主要就是查询字段信息,循环生成Mode字段,就完了。

        /// <summary>
        /// 查询Mysql表字段信息
        /// </summary>
        /// <param name="tableName">表名</param>
        /// <returns></returns>
        public List<TableSchemaModel> GetTableSchemaData(string tableName)
        {
            List<TableSchemaModel> ret = null;
            var tableSchema = dbContext.Database.Connection.Database;
            string sql = string.Format("SELECT table_name TableName,column_Name ColumnName,is_nullable IsNullable,data_type DataType,character_maximum_length CharacterMaximumLength,column_comment ColumnComment,Column_Key ColumnKey FROM information_schema.COLUMNS WHERE table_schema='{0}' AND table_name = '{1}';", tableSchema, tableName);
            ret = ExecuteQuerySql<TableSchemaModel>(sql);
            return ret;
        }
        /// <summary>
        /// 查询表中字段关联的所有外键表信息
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public List<TableRefrenceModel> GetTableRefrenceData(string tableName)
        {
            List<TableRefrenceModel> ret = null;
            var tableSchema = dbContext.Database.Connection.Database;
            string sql = string.Format("SELECT table_name TableName,column_name ColumnName,REFERENCED_TABLE_NAME ReferencedTableName,REFERENCED_COLUMN_NAME ReferencedColumnName FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE table_schema='{0}' AND table_name = '{1}';", tableSchema, tableName);
            ret = ExecuteQuerySql<TableRefrenceModel>(sql);
            return ret;
        } 

        /// <summary>
        /// 生成Model类文件中的非导航属性内容,到bin/Files 目录 的 tableName.cs文件
        /// </summary>
        /// <param name="tableName">表名,也是生成的Model类名</param>
        public void GenerateModelJob(string tableName)
        {
            var data = taskRepository.GetTableSchemaData(tableName);
            if (data != null)
            {
                var refrenceData = taskRepository.GetTableRefrenceData(tableName);
                var priColumn = data.Where(o => o.ColumnKey == "PRI").First();
                StringBuilder sb = new StringBuilder();
                sb.Append(@"
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;

");
                sb.AppendFormat("    [Table(\"{0}\")]", tableName).AppendLine();
                sb.AppendFormat(@"    public partial class {0} : Entity<{1}>
", tableName, GetCSTypeFromDbType(priColumn.DataType)).Append("    {").AppendLine();
                foreach (var field in data)
                {
                    sb.AppendFormat(@"
        /// <summary>
        /// {0}
        /// </summary>
", field.ColumnComment);

                    switch (field.DataType)
                    {
                        case "varchar":
                        case "nvarchar":
                            {
                                sb.AppendFormat(@"        [StringLength({0})]
        [MaxLength({0})]
", field.CharacterMaximumLength);
                            }
                            break;
                        case "date":
                        case "bit":
                            {
                                sb.AppendFormat("        [Column(TypeName = \"{0}\")]", field.DataType).AppendLine();
                            }
                            break;
                    }
                    if (field.ColumnKey == "PRI")
                    {
                        sb.AppendFormat("        [Column(\"{0}\")]", field.ColumnName).AppendLine();
                        sb.AppendFormat("        public override {0} Id ", GetCSTypeFromDbType(field.DataType)).Append("{ get; set; }").AppendLine();
                    }
                    else
                    {
                        sb.AppendFormat("        public {0}{1} {2} ", GetCSTypeFromDbType(field.DataType), field.IsNullable == "YES" ? "?" : "", field.ColumnName).Append("{ get; set; }").AppendLine();
                    }
                }
                foreach (var refrence in refrenceData)
                {
                    sb.AppendFormat("        public virtual {0} {0} ", refrence.ReferencedTableName).Append("{ get; set; }").AppendLine();
                }
                sb.Append(@"
    }
}
");
                var str = sb.ToString();
                string saveDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files\\");
                if (!Directory.Exists(saveDir)) Directory.CreateDirectory(saveDir);
                string saveFilePath = System.IO.Path.Combine(saveDir, tableName + ".cs");
                System.IO.File.AppendAllText(saveFilePath, str, Encoding.UTF8);
            }
        }

        /// <summary>
        /// Mysql数据库字段类型转化为C#字段类型
        /// </summary>
        /// <param name="dbType"></param>
        /// <returns></returns>
        private string GetCSTypeFromDbType(string dbType)
        {
            string ret = dbType;
            switch (dbType)
            {
                case "nvarchar":
                case "text":
                case "varchar": ret = "string"; break;
                case "datetime":
                case "date": ret = "DateTime"; break;
                case "bit": ret = "bool"; break;
                case "bigint": ret = "long"; break;
            }
            return ret;
        }





二、与Sql Server简单对比

 1、从上面可以看到,查询MySql表结构的语句非常简单,全部的信息全部可以从information_schema.COLUMNS 这个对象里面查,还有外键表字段等等关联关系,全部都可以从INFORMATION_SCHEMA.KEY_COLUMN_USAGE对象查出来,只要传入指定的数据库名和表名就行了,相对 来说,Sql Server就复杂很多,如果一样要生成这个Model类,估计会非常头痛!


2、刚接触Mysql感觉有一些坑,比如存储过程的使用和Sql Server不一样、在.Net的EF中Mysql事务的使用和Sql Server不一样。最大的不同是,Mysql可以设置语句是否立即执行,如果没设置为true,在程序中调用SQL语句操作数据,都不会成功保存到数据库,后面都要加一个 commit; 才行。

现在用过一段时间,还行,有些东西注意一下就和sql server差不多。





相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
5月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
990 152
|
5月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎
阿里云数据库RDS支持MySQL、SQL Server、PostgreSQL和MariaDB引擎,提供高性价比、稳定安全的云数据库服务,适用于多种行业与业务场景。
804 156
|
5月前
|
SQL 人工智能 Linux
SQL Server 2025 RC1 发布 - 从本地到云端的 AI 就绪企业数据库
SQL Server 2025 RC1 发布 - 从本地到云端的 AI 就绪企业数据库
520 5
SQL Server 2025 RC1 发布 - 从本地到云端的 AI 就绪企业数据库
|
10月前
|
SQL 数据库 数据安全/隐私保护
数据库数据恢复——sql server数据库被加密的数据恢复案例
SQL server数据库数据故障: SQL server数据库被加密,无法使用。 数据库MDF、LDF、log日志文件名字被篡改。 数据库备份被加密,文件名字被篡改。
|
5月前
|
关系型数据库 分布式数据库 数据库
阿里云数据库收费价格:MySQL、PostgreSQL、SQL Server和MariaDB引擎费用整理
阿里云数据库提供多种类型,包括关系型与NoSQL,主流如PolarDB、RDS MySQL/PostgreSQL、Redis等。价格低至21元/月起,支持按需付费与优惠套餐,适用于各类应用场景。
|
6月前
|
SQL 人工智能 Linux
SQL Server 2025 RC0 发布 - 从本地到云端的 AI 就绪企业数据库
SQL Server 2025 RC0 发布 - 从本地到云端的 AI 就绪企业数据库
334 5
|
7月前
|
SQL 存储 数据库
SQL Server Management Studio (SSMS) 21 - 微软数据库管理工具
SQL Server Management Studio (SSMS) 21 - 微软数据库管理工具
1195 0
|
7月前
|
SQL XML Java
配置Spring框架以连接SQL Server数据库
最后,需要集成Spring配置到应用中,这通常在 `main`方法或者Spring Boot的应用配置类中通过加载XML配置或使用注解来实现。
579 0
|
9月前
|
SQL 人工智能 数据库
SQL Server 2025 - 从本地到云端的 AI 就绪企业数据库
SQL Server 2025 - 从本地到云端的 AI 就绪企业数据库
667 0
SQL Server 2025 - 从本地到云端的 AI 就绪企业数据库
|
11月前
|
SQL 数据库连接 Linux
数据库编程:在PHP环境下使用SQL Server的方法。
看看你吧,就像一个调皮的小丑鱼在一片广阔的数据库海洋中游弋,一路上吞下大小数据如同海中的珍珠。不管有多少难关,只要记住这个流程,剩下的就只是探索未知的乐趣,沉浸在这个充满挑战的数据库海洋中。
318 16

推荐镜像

更多