【问题标题】:How to create a models class from SQL Server如何从 SQL Server 创建模型类
【发布时间】:2021-07-02 12:35:53
【问题描述】:

如何从 SQL Server 创建模型(.cs)类?

我将传递 SQL 服务器的连接字符串和项目名称,然后它将为每个表生成一个类,并且还会考虑类中的外键。

像这样:

public class BankInfo
    {
        [JsonProperty("BankId")]
        public string BankId { get; set; }

        [JsonProperty("BankName")]
        public string BankName { get; set; }

        [JsonProperty("BankPhone")]
        public string BankPhone { get; set; }
    }

【问题讨论】:

    标签: c# sql-server class


    【解决方案1】:

    可以从以下GitHub repository 克隆以下代码,用于测试修改后的 NorthWind 数据库,请参阅the script here

    1. 代码是使用 C#9、.NET Core 5 编写的,只需稍加调整即可与早期版本的 .NET Framework 一起使用
    2. 核心代码灵感来自this post

    示例创建类

    public class Contacts
    {
        [JsonProperty("ContactId")]
        public int ContactId { get; set; }
    
        [JsonProperty("FirstName")]
        public string FirstName { get; set; }
    
        [JsonProperty("LastName")]
        public string LastName { get; set; }
    
        [JsonProperty("ContactTypeIdentifier")]
        public int? ContactTypeIdentifier { get; set; }
    }
    

    在 DataOperations 类中,从文本文件中读取查询以生成特定数据库中每个表的类文件。 从存储库代码运行代码

    DataOperations.Server = ".\\SQLEXPRESS";
    DataOperations.Database = "NorthWind2020";
    DataOperations.OutputFolder = "Classes";
    
    DataOperations.Create();
    

    在您的项目中运行此代码时,请确保在与您的可执行文件相同的文件夹下创建一个名为 Classes 的文件夹。

    DataOperations.cs

    using System.Data;
    using System.Data.SqlClient;
    using System.IO;
    
    namespace CreateClassesFromSqlServer
    {
        public class DataOperations
        {
            /// <summary>
            /// SQL-Server name
            /// </summary>
            public static string Server { get; set; }
            /// <summary>
            /// Database in Server
            /// </summary>
            public static string Database { get; set; }
            /// <summary>
            /// Location to create classes
            /// </summary>
            public static string OutputFolder { get; set; }
            
            /// <summary>
            /// Iterate <see cref="Database"/> tables, create classes from
            /// SQL in the file ClassQuery.txt
            /// </summary>
            public static void Create()
            {
                var classQuery = File.ReadAllText("ClassQuery.txt");
                using var connection = new SqlConnection($"Server={Server};Database={Database};Integrated Security=true");
                
                connection.Open();
                
                var adapter = new SqlDataAdapter(
                    "SELECT TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, TABLE_TYPE " +
                    $"FROM INFORMATION_SCHEMA.TABLES WHERE (TABLE_TYPE = 'BASE TABLE') AND (TABLE_CATALOG = '{Database}') AND (TABLE_NAME != N'sysdiagrams') " + 
                    "ORDER BY TABLE_NAME", connection);
                
                DataTable table = new DataTable();
                adapter.Fill(table);
    
                foreach (DataRow row in table.Rows)
                {
                    var tableName = row["TABLE_NAME"].ToString();
                    var fileName = tableName + ".cs";
    
                    string sql = $"declare @TableName sysname = '{tableName}'{classQuery}";
    
                    using var cmd = new SqlCommand(sql, connection);
                    string code = (string)cmd.ExecuteScalar();
    
                    if (File.Exists(Path.Combine(OutputFolder, fileName)))
                    {
                        File.Delete(Path.Combine(OutputFolder, fileName));
                    }
                    
                    File.WriteAllText(Path.Combine(OutputFolder, fileName), code);
    
                }
            }
    
    
        }
    }
    

    查询生成类文件

    declare @Result varchar(max) = 'public class ' + @TableName + '
    {'
    
    select @Result = @Result + CHAR(13) + '    [JsonProperty("' + ColumnName + '")]
        public ' + ColumnType + NullableSign + ' ' + ColumnName + ' { get; set; }
    '
    from
    (
        select 
            replace(col.name, ' ', '_') ColumnName,
            column_id ColumnId,
            case typ.name 
                when 'bigint' then 'long'
                when 'binary' then 'byte[]'
                when 'bit' then 'bool'
                when 'char' then 'string'
                when 'date' then 'DateTime'
                when 'datetime' then 'DateTime'
                when 'datetime2' then 'DateTime'
                when 'datetimeoffset' then 'DateTimeOffset'
                when 'decimal' then 'decimal'
                when 'float' then 'double'
                when 'image' then 'byte[]'
                when 'int' then 'int'
                when 'money' then 'decimal'
                when 'nchar' then 'string'
                when 'ntext' then 'string'
                when 'numeric' then 'decimal'
                when 'nvarchar' then 'string'
                when 'real' then 'float'
                when 'smalldatetime' then 'DateTime'
                when 'smallint' then 'short'
                when 'smallmoney' then 'decimal'
                when 'text' then 'string'
                when 'time' then 'TimeSpan'
                when 'timestamp' then 'long'
                when 'tinyint' then 'byte'
                when 'uniqueidentifier' then 'Guid'
                when 'varbinary' then 'byte[]'
                when 'varchar' then 'string'
                else 'UNKNOWN_' + typ.name
            end ColumnType,
            case 
                when col.is_nullable = 1 and typ.name in ('bigint', 'bit', 'date', 'datetime', 'datetime2', 'datetimeoffset', 'decimal', 'float', 'int', 'money', 'numeric', 'real', 'smalldatetime', 'smallint', 'smallmoney', 'time', 'tinyint', 'uniqueidentifier') 
                then '?' 
                else '' 
            end NullableSign
        from sys.columns col
            join sys.types typ on
                col.system_type_id = typ.system_type_id AND col.user_type_id = typ.user_type_id
        where object_id = object_id(@TableName)
    ) t
    order by ColumnId
    
    set @Result = @Result  + '}'
    select @Result
    

    重要

    不保证代码适合所有情况,尚未针对所有可能的情况进行全面测试。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-10
      • 1970-01-01
      • 2016-08-20
      • 2021-09-07
      相关资源
      最近更新 更多