如何从SQL Server表对象生成类?

我说的不是使用ORM。我只需要创建实体(简单类)。喜欢的东西:

    public class Person 
    {
        public string Name { get;set; }
        public string Phone { get;set; }
    }

给定一个表,比如:

+----+-------+----------------+
| ID | Name  |     Phone      |
+----+-------+----------------+
|  1 | Alice | (555) 555-5550 |
|  2 | Bob   | (555) 555-5551 |
|  3 | Cathy | (555) 555-5552 |
+----+-------+----------------+



当前回答

我尝试过node.js,它对我来说工作得很好。

它将为您创建模型文件。您可以创建多个模型文件

前提条件:安装node.js

需要更改:

在你的工作区中创建index.js文件 在“allTable”中添加你的tables对象(截图中高亮显示) 更改文件夹路径(我已经给出了我的系统路径) 执行命令节点index.js

节点index.js

输出

const fs = require('fs/promises'); async function convertToDataType(dataArray, fileName) { let count = 0; let tempArray = []; var dataTypeArray = [ { "key": "bigint", "value": "long" }, { "key": "binary", "value": "byte[]" }, { "key": "bit", "value": "bool" }, { "key": "char", "value": "string" }, { "key": "date", "value": "DateTime" }, { "key": "datetime", "value": "DateTime" }, { "key": "datetime2", "value": "DateTime" }, { "key": "datetimeoffset", "value": "DateTimeOffset" }, { "key": "decimal", "value": "decimal" }, { "key": "float", "value": "double" }, { "key": "image", "value": "byte[]" }, { "key": "int", "value": "int" }, { "key": "money", "value": "decimal" }, { "key": "nchar", "value": "string" }, { "key": "ntext", "value": "string" }, { "key": "numeric", "value": "decimal" }, { "key": "nvarchar", "value": "string" }, { "key": "real", "value": "float" }, { "key": "smalldatetime", "value": "DateTime" }, { "key": "smallint", "value": "short" }, { "key": "smallmoney", "value": "decimal" }, { "key": "text", "value": "string" }, { "key": "time", "value": "TimeSpan" }, { "key": "timestamp", "value": "long" }, { "key": "tinyint", "value": "byte" }, { "key": "uniqueidentifier", "value": "Guid" }, { "key": "varbinary", "value": "byte[]" }, { "key": "varchar", "value": "string" } ] dataArray.map(i => { let objDataType = ''; objDataType = dataTypeArray.filter(data => data.key == i.split(' ')[1].replace('[', '').replace(']', ''))[0].value; if (objDataType == '') { count++; } let isNull = i.includes('NULL') && !(i.includes('varchar') || i.includes('bit')) ? '?' : ''; isNull = i.includes('NOT NULL') ? '' : isNull; const varValue = i.split(' ')[0].replace('[', '').replace(']', ''); if (count != 0) { console.warn(`\n\n\n ======> Error:: Check data type is missing. Datatype => ${i.split(' ')[1]} Object Name: ${fileName} \n\n\n`); } else { tempArray.push(`public ${objDataType}${isNull} ${varValue} { get; set; }`); } }); return tempArray; } async function convertToModel() { try { let allTable = { EmployeeAllowancesHistory: [ "[EmployeeAllowanceHistoryID] [int] NOT NULL", "[EmployeeID] [int] NOT NULL", "[AllowanceID] [int] NOT NULL", "[DateID] [int] NULL", "[Amount] [numeric] NOT NULL", "[Insured] [bit] NULL", "[ChangeDate] [datetime] NOT NULL", "[NewAmount] [numeric] NULL" ], Cities: [ "[CityID] [int] NOT NULL", "[CityCode] [varchar] NOT NULL", "[CityNameAr] [varchar] NULL", "[CityNameEn] [varchar] NULL", "[InKSA] [bit] NOT NULL", "[HighClass] [bit] NOT NULL", "[TravelDays] [int] NULL" ], Regions: [ "[RegionID] [int] NOT NULL", "[RegionCode] [nvarchar] NULL", "[RegionNameEn] [nvarchar] NULL", "[RegionNameAr] [nvarchar] NULL", "[CityID] [int] NULL" ] } for (var file in allTable) { const tableObject = await convertToDataType(allTable[file], file); let tempContent = "[key]"; tableObject.map(obj => { tempContent = `${tempContent} ${obj}` }); const content = `using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Core.Entities { public class ${file} { ${tempContent} } }` fs.writeFile(`/model_files/${file}.cs`, content); } console.log('Created successfully...'); } catch (err) { console.log(err); } } convertToModel();

其他回答

我无法让亚历克斯的答案在Sql Server 2008 R2上工作。所以,我用同样的基本原理重写了它。它现在支持模式,并且对列属性映射(包括将可为空的日期类型映射为可为空的c#值类型)进行了一些修复。下面是Sql语句:

   DECLARE @TableName VARCHAR(MAX) = 'NewsItem' -- Replace 'NewsItem' with your table name
    DECLARE @TableSchema VARCHAR(MAX) = 'Markets' -- Replace 'Markets' with your schema name
    DECLARE @result varchar(max) = ''

    SET @result = @result + 'using System;' + CHAR(13) + CHAR(13) 

    IF (@TableSchema IS NOT NULL) 
    BEGIN
        SET @result = @result + 'namespace ' + @TableSchema  + CHAR(13) + '{' + CHAR(13) 
    END

    SET @result = @result + 'public class ' + @TableName + CHAR(13) + '{' + CHAR(13) 

    SET @result = @result + '#region Instance Properties' + CHAR(13)  

   SELECT
      @result = @result + CHAR(13)
      + ' public ' + ColumnType + ' ' + ColumnName + ' { get; set; } ' + CHAR(13)
    FROM (SELECT
      c.COLUMN_NAME AS ColumnName,
      CASE c.DATA_TYPE
        WHEN 'bigint' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Int64?'
            ELSE 'Int64'
          END
        WHEN 'binary' THEN 'Byte[]'
        WHEN 'bit' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'bool?'
            ELSE 'bool'
          END
        WHEN 'char' THEN 'string'
        WHEN 'date' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'DateTime?'
            ELSE 'DateTime'
          END
        WHEN 'datetime' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'DateTime?'
            ELSE 'DateTime'
          END
        WHEN 'datetime2' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'DateTime?'
            ELSE 'DateTime'
          END
        WHEN 'datetimeoffset' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'DateTimeOffset?'
            ELSE 'DateTimeOffset'
          END
        WHEN 'decimal' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'decimal?'
            ELSE 'decimal'
          END
        WHEN 'float' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Single?'
            ELSE 'Single'
          END
        WHEN 'image' THEN 'Byte[]'
        WHEN 'int' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'int?'
            ELSE 'int'
          END
        WHEN 'money' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'decimal?'
            ELSE 'decimal'
          END
        WHEN 'nchar' THEN 'string'
        WHEN 'ntext' THEN 'string'
        WHEN 'numeric' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'decimal?'
            ELSE 'decimal'
          END
        WHEN 'nvarchar' THEN 'string'
        WHEN 'real' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Double?'
            ELSE 'Double'
          END
        WHEN 'smalldatetime' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'DateTime?'
            ELSE 'DateTime'
          END
        WHEN 'smallint' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Int16?'
            ELSE 'Int16'
          END
        WHEN 'smallmoney' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'decimal?'
            ELSE 'decimal'
          END
        WHEN 'text' THEN 'string'
        WHEN 'time' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'TimeSpan?'
            ELSE 'TimeSpan'
          END
        WHEN 'timestamp' THEN 'Byte[]'
        WHEN 'tinyint' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Byte?'
            ELSE 'Byte'
          END
        WHEN 'uniqueidentifier' THEN CASE C.IS_NULLABLE
            WHEN 'YES' THEN 'Guid?'
            ELSE 'Guid'
          END
        WHEN 'varbinary' THEN 'Byte[]'
        WHEN 'varchar' THEN 'string'
        ELSE 'Object'
      END AS ColumnType,
      c.ORDINAL_POSITION
    FROM INFORMATION_SCHEMA.COLUMNS c
    WHERE c.TABLE_NAME = @TableName
    AND ISNULL(@TableSchema, c.TABLE_SCHEMA) = c.TABLE_SCHEMA) t
    ORDER BY t.ORDINAL_POSITION

    SET @result = @result + CHAR(13) + '#endregion Instance Properties' + CHAR(13)  

    SET @result = @result  + '}' + CHAR(13)

    IF (@TableSchema IS NOT NULL) 
    BEGIN
        SET @result = @result + CHAR(13) + '}' 
    END

    PRINT @result

它生成的c#代码如下所示:

using System;

namespace Markets
{
    public class NewsItem        {
        #region Instance Properties

        public Int32 NewsItemID { get; set; }

        public Int32? TextID { get; set; }

        public String Description { get; set; }

        #endregion Instance Properties
    }

}

It may be an idea to use EF, Linq to Sql, or even Scaffolding; however, there are times when a piece of coding like this comes in handy. Frankly, I do not like using EF navigation properties where the code it generates made 19,200 separate database calls to populate a 1000 row grid. This could have been achieved in a single database call. Nonetheless, it could just be that your technical architect does not want you to use EF and the like. So, you have to revert to code like this... Incidentally, it may also be an idea to decorate each of the properties with attributes for DataAnnotations, etc., but I'm keeping this strictly POCO.

编辑 修正了时间戳和Guid?

为了感谢Alex的解决方案和Guilherme的要求,我为MySQL生成c#类做了这个

set @schema := 'schema_name';
set @table := 'table_name';
SET group_concat_max_len = 2048;
SELECT 
    concat('public class ', @table, '\n{\n', GROUP_CONCAT(a.property_ SEPARATOR '\n'), '\n}') class_
FROM 
    (select
        CONCAT(
        '\tpublic ',
        case 
            when DATA_TYPE = 'bigint' then 'long'
            when DATA_TYPE = 'BINARY' then 'byte[]'
            when DATA_TYPE = 'bit' then 'bool'
            when DATA_TYPE = 'char' then 'string'
            when DATA_TYPE = 'date' then 'DateTime'
            when DATA_TYPE = 'datetime' then 'DateTime'
            when DATA_TYPE = 'datetime2' then 'DateTime'
            when DATA_TYPE = 'datetimeoffset' then 'DateTimeOffset'
            when DATA_TYPE = 'decimal' then 'decimal'
            when DATA_TYPE = 'double' then 'double'
            when DATA_TYPE = 'float' then 'float'
            when DATA_TYPE = 'image' then 'byte[]'
            when DATA_TYPE = 'int' then 'int'
            when DATA_TYPE = 'money' then 'decimal'
            when DATA_TYPE = 'nchar' then 'char'
            when DATA_TYPE = 'ntext' then 'string'
            when DATA_TYPE = 'numeric' then 'decimal'
            when DATA_TYPE = 'nvarchar' then 'string'
            when DATA_TYPE = 'real' then 'double'
            when DATA_TYPE = 'smalldatetime' then 'DateTime'
            when DATA_TYPE = 'smallint' then 'short'
            when DATA_TYPE = 'smallmoney' then 'decimal'
            when DATA_TYPE = 'text' then 'string'
            when DATA_TYPE = 'time' then 'TimeSpan'
            when DATA_TYPE = 'timestamp' then 'DateTime'
            when DATA_TYPE = 'tinyint' then 'byte'
            when DATA_TYPE = 'uniqueidentifier' then 'Guid'
            when DATA_TYPE = 'varbinary' then 'byte[]'
            when DATA_TYPE = 'varchar' then 'string'
            else '_UNKNOWN_'
        end, ' ', 
        COLUMN_NAME, ' {get; set;}') as property_
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE table_name = @table AND table_schema = @schema) a
;

谢谢Alex和Guilherme!

我很困惑你想要从这里得到什么,但这里是在设计你想要设计的东西时的一般选择。

在Visual Studio版本中使用内置的ORM。 自己编写一个,类似于您的代码示例。通常情况下,如果你不确定怎么做,教程是你最好的朋友。 使用另一种ORM,如NHibernate。

如果你可以访问SQL Server 2016,你可以使用FOR JSON(包含INCLUDE_NULL_VALUES)选项从选择语句中获取JSON输出。复制输出,然后在Visual Studio中,粘贴special ->,粘贴JSON作为类。

算是预算上的解决方案,但可能会节省一些时间。

商业化,但codessmith Generator做到了:http://www.codesmithtools.com/product/generator