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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
简介: 最近的一个项目,在.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差不多。





相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3月前
|
SQL 开发框架 .NET
ASP.NET连接SQL数据库:详细步骤与最佳实践指南ali01n.xinmi1009fan.com
随着Web开发技术的不断进步,ASP.NET已成为一种非常流行的Web应用程序开发框架。在ASP.NET项目中,我们经常需要与数据库进行交互,特别是SQL数据库。本文将详细介绍如何在ASP.NET项目中连接SQL数据库,并提供最佳实践指南以确保开发过程的稳定性和效率。一、准备工作在开始之前,请确保您
349 3
|
3月前
|
开发框架 .NET C#
C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
【10月更文挑战第9天】在 C#/.NET Core 中,有多种方法可以删除字符串的最后一个字符,包括使用 `Substring` 方法、`Remove` 方法、`ToCharArray` 与 `Array.Copy`、`StringBuilder`、正则表达式、循环遍历字符数组以及使用 LINQ 的 `SkipLast` 方法。
107 8
|
21天前
|
JSON 安全 API
.net 自定义日志类
在.NET中,创建自定义日志类有助于更好地管理日志信息。示例展示了如何创建、配置和使用日志记录功能,包括写入日志文件、设置日志级别、格式化消息等。注意事项涵盖时间戳、日志级别、JSON序列化、线程安全、日志格式、文件处理及示例使用。请根据需求调整代码。
44 13
|
26天前
|
SQL 存储 关系型数据库
MySQL/SqlServer跨服务器增删改查(CRUD)的一种方法
通过上述方法,MySQL和SQL Server均能够实现跨服务器的增删改查操作。MySQL通过联邦存储引擎提供了直接的跨服务器表访问,而SQL Server通过链接服务器和分布式查询实现了灵活的跨服务器数据操作。这些技术为分布式数据库管理提供了强大的支持,能够满足复杂的数据操作需求。
78 12
|
27天前
|
JSON 数据格式
.net HTTP请求类封装
`HttpRequestHelper` 是一个用于简化 HTTP 请求的辅助类,支持发送 GET 和 POST 请求。它使用 `HttpClient` 发起请求,并通过 `Newtonsoft.Json` 处理 JSON 数据。示例展示了如何使用该类发送请求并处理响应。注意事项包括:简单的错误处理、需安装 `Newtonsoft.Json` 依赖,以及建议重用 `HttpClient` 实例以优化性能。
70 2
|
2月前
|
数据库 C# 开发者
ADO.NET连接到南大通用GBase 8s数据库
ADO.NET连接到南大通用GBase 8s数据库
|
2月前
|
存储 缓存 NoSQL
2款使用.NET开发的数据库系统
2款使用.NET开发的数据库系统
|
2月前
|
数据库连接 数据库 C#
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(上)
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(上)
|
2月前
|
数据库连接 数据库 C#
Windows下C# 通过ADO.NET方式连接南大通用GBase 8s数据库(下)
本文接续前文,深入讲解了在Windows环境下使用C#和ADO.NET操作南大通用GBase 8s数据库的方法。通过Visual Studio 2022创建项目,添加GBase 8s的DLL引用,并提供了详细的C#代码示例,涵盖数据库连接、表的创建与修改、数据的增删查改等操作,旨在帮助开发者提高数据库管理效率。
|
3月前
|
关系型数据库 MySQL Java
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。
这篇文章是关于如何使用Django框架配置MySQL数据库,创建模型实例,并自动或手动创建数据库表,以及对这些表进行操作的详细教程。
124 0
Django学习二:配置mysql,创建model实例,自动创建数据库表,对mysql数据库表已经创建好的进行直接操作和实验。