如何使用Dapper从数据库生成模型?

27

我来自 PetaPoco 阵营。PetaPoco 有一个 T4 模板,可以从数据库生成模型。Dapper 有类似的功能吗?

我使用 NuGet 安装了 Dapper 并添加了 SqlHelper.cs,但是我没有找到任何能够从数据库生成模型的工具。

13个回答

59

我最近刚写了一条SQL查询来完成我的工作,需要时还会更新它以添加额外的类型。只需替换说@@ @@处的表名即可。

为了创建大量表格,我创建了一个临时存储过程来调用。例如: exec createTablePOCO(@tableName)

SELECT 
    'public ' + a1.NewType + ' ' + a1.COLUMN_NAME + ' {get;set;}'
    ,*
FROM (
    /*using top because i'm putting an order by ordinal_position on it. 
    putting a top on it is the only way for a subquery to be ordered*/
    SELECT TOP 100 PERCENT
    COLUMN_NAME,
    DATA_TYPE,
    IS_NULLABLE,
    CASE 
        WHEN DATA_TYPE = 'varchar' THEN 'string'
        WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'NO' THEN 'DateTime'
        WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'YES' THEN 'DateTime?'
        WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'YES' THEN 'int?'
        WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'NO' THEN 'int'
        WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'NO' THEN 'Int16'
        WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'YES' THEN 'Int16?'
        WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'NO' THEN 'decimal'
        WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'YES' THEN 'decimal?'
        WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'NO' THEN 'decimal'
        WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'YES' THEN 'decimal?'
        WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'NO' THEN 'decimal'
        WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'YES' THEN 'decimal?'
        WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'NO' THEN 'long'
        WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'YES' THEN 'long?'
        WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'NO' THEN 'byte'
        WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'YES' THEN 'byte?'
        WHEN DATA_TYPE = 'char' THEN 'string'
        WHEN DATA_TYPE = 'timestamp' THEN 'byte[]'
        WHEN DATA_TYPE = 'varbinary' THEN 'byte[]'
        WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'NO' THEN 'bool'
        WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'YES' THEN 'bool?'
        WHEN DATA_TYPE = 'xml' THEN 'string'
    END AS NewType
    FROM INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = '@@@@'
    ORDER BY ORDINAL_POSITION
) as a1

1
我喜欢这个小脚本。如果你想要从现有表格快速生成一个简单的POCO,那么没有比这更容易的了。如果你需要映射更多的字段,请使用此链接查找它们。http://msdn.microsoft.com/en-us/library/ms131092.aspx - James Roland
不要忘记当数据类型为'nvarchar'时,应该写作'string'。 - Jeroen K
1
我添加了以下两行代码 WHEN DATA_TYPE = 'nvarchar' THEN 'string' WHEN DATA_TYPE = 'uniqueidentifier' THEN 'Guid' - khebbie
可能还需要添加以下内容:当 DATA_TYPE = 'date' 且 IS_NULLABLE = 'NO' 时,返回 'DateTime' 当 DATA_TYPE = 'date' 且 IS_NULLABLE = 'YES' 时,返回 'DateTime?' 当 DATA_TYPE = 'smallmoney' 且 IS_NULLABLE = 'NO' 时,返回 'decimal' 当 DATA_TYPE = 'smallmoney' 且 IS_NULLABLE = 'YES' 时,返回 'decimal?' - Razze
5
当数据类型类似于 '%char%' 时,则翻译为 'string'。 - Jason Watts
1
抱歉,我不擅长 SQL。但是你能否提供在 C# 语言中如何使用 Dapper 的示例代码? - fiberOptics

7

Dapper本身为连接对象提供了少量的扩展方法(Query,Execute),并且没有“模型生成器”。也许可以使用其他框架根据数据库模式生成POCO。

更新:

数据库表到C# POCO类T4模板

<#@ template language="C#" debug="True" #>

<#@ assembly name="System" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Xml" #>

<#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #>
<#@ assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #>
<#@ assembly name="Microsoft.SqlServer.Smo" #>

<#@ import namespace="System" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="Microsoft.SqlServer.Management.Smo" #>
<#@ import namespace="System.Data.SqlClient" #>
<#@ import namespace="Microsoft.SqlServer.Management.Common" #>

namespace Namespace
{

<#         
   var databaseName = "testDb";
            var serverConnection = new SqlConnection(
                    @"Data Source=.\SQLEXPRESS; Integrated Security=true; Initial Catalog=" + databaseName);
            var svrConnection = new ServerConnection(serverConnection);

   Server srv = new Server(svrConnection);
            foreach (Table table in srv.Databases[databaseName].Tables)
            {

#>
        class <#= table.Name #>
        {
            <#
                foreach (Column col in table.Columns)
                {
                #>
                    public <#= GetNetDataType(col.DataType.Name) #> <#= col.Name #> { get; set; }
                <#
                }
             #>
        }

<#            }
#>
}



<#+
        public static string GetNetDataType(string sqlDataTypeName)
        {

            switch (sqlDataTypeName.ToLower())
            {
                case "bigint":
                    return "Int64";
                case "binary":
                    return "Byte[]";
                case "bit":
                    return "bool";
                case "char":
                    return "char";
                case "cursor":
                    return string.Empty;
                case "datetime":
                    return "DateTime";
                case "decimal":
                    return "Decimal";
                case "float":
                    return "Double";
                case "int":
                    return "int";
                case "money":
                    return "Decimal";
                case "nchar":
                    return "string";
                case "numeric":
                    return "Decimal";
                case "nvarchar":
                    return "string";
                case "real":
                    return "single";
                case "smallint":
                    return "Int16";
                case "text":
                    return "string";
                case "tinyint":
                    return "Byte";
                case "varbinary":
                    return "Byte[]";
                case "xml":
                    return "string";
                case "varchar":
                    return "string";
                case "smalldatetime":
                    return "DateTime";
                case "image":
                    return "byte[]";

                default:
                    return string.Empty;
            }



        }
#>

我没有使用以下任何工具,但你可以看一下这个链接:http://visualstudiogallery.msdn.microsoft.com/23df0450-5677-4926-96cc-173d02752313 和 https://sites.google.com/site/mrmbookmarks/msg/t4-generatepocofromalltablesinadatabase - Void Ray
1
还有更复杂的代码生成器,例如:http://www.codesmithtools.com/ - Void Ray
5
我稍微调整了“从所有表生成POCO”的模板,看起来是一个不错的起点;它可以执行基本的表格到类的转换。在测试时,我遇到了一些问题,这强迫我对其进行了一些修改;这里是更新版本的链接:http://teamyudin.blogspot.com/2012/06/database-tables-to-c-poco-classes-t4.html。 - Void Ray
1
@RobertKoritnik 我只想要包含Getter和Setter的类。 - RKh
1
对于谷歌员工,可以查看此存储库 https://github.com/shps951023/PocoClassGenerator。它可以帮助您从多种类型的数据库生成 poco 类。易于使用。 - Rohim Chou
显示剩余2条评论

7

从游标中调用存储过程

如果您将Mattritchies提到的存储过程组合起来,并从游标中调用它,您可以为数据库中的每个表生成POCO类。

USE YourDataBaseName
GO 
    DECLARE @field1 nvarchar(400)
    DECLARE cur CURSOR LOCAL for

    SELECT TABLE_NAME FROM information_schema.tables
    OPEN cur
    FETCH NEXT FROM cur INTO @field1 --, @field2
    WHILE @@FETCH_STATUS = 0 BEGIN          
        exec Helper_CreatePocoFromTableName @field1 -- , @field2            
        fetch next from cur into @field1 -- , @field2
    END

close cur
deallocate cur

mattritchies提到的存储过程

我使用了mattritchies上面提供的sql,并创建了他提到的存储过程,在此基础上进行了一些修改,使其添加了类名。如果您将Management Studio设置为文本输出模式并删除列名输出,则可以获得所有类的复制粘贴文本:

CREATE PROCEDURE [dbo].[Helper_CreatePocoFromTableName]    
    @tableName varchar(100)
AS
BEGIN
SET NOCOUNT ON;

-- Subquery to return only the copy paste text
Select PropertyColumn from (
    SELECT 1 as rowNr, 'public class ' + @tableName + ' {' as PropertyColumn
    UNION
    SELECT 2 as rowNr, 'public ' + a1.NewType + ' ' + a1.COLUMN_NAME + ' {get;set;}' as PropertyColumn
    -- ,* comment added so that i get copy pasteable output
     FROM 
    (
        /*using top because i'm putting an order by ordinal_position on it. 
        putting a top on it is the only way for a subquery to be ordered*/
        SELECT TOP 100 PERCENT
        COLUMN_NAME,
        DATA_TYPE,
        IS_NULLABLE,
        CASE 
            WHEN DATA_TYPE = 'varchar' THEN 'string'
            WHEN DATA_TYPE = 'nvarchar' THEN 'string' 
            WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'NO' THEN 'DateTime'
            WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'YES' THEN 'DateTime?'
            WHEN DATA_TYPE = 'smalldatetime' AND IS_NULLABLE = 'NO' THEN 'DateTime'
            WHEN DATA_TYPE = 'datetime2' AND IS_NULLABLE = 'NO' THEN 'DateTime'
            WHEN DATA_TYPE = 'smalldatetime' AND IS_NULLABLE = 'YES' THEN 'DateTime?'
            WHEN DATA_TYPE = 'datetime2' AND IS_NULLABLE = 'YES' THEN 'DateTime?'
            WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'YES' THEN 'int?'
            WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'NO' THEN 'int'
            WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'NO' THEN 'Int16'
            WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'YES' THEN 'Int16?'
            WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'NO' THEN 'decimal'
            WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'YES' THEN 'decimal?'
            WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'NO' THEN 'decimal'
            WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'YES' THEN 'decimal?'
            WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'NO' THEN 'decimal'
            WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'YES' THEN 'decimal?'
            WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'NO' THEN 'long'
            WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'YES' THEN 'long?'
            WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'NO' THEN 'byte'
            WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'YES' THEN 'byte?'
            WHEN DATA_TYPE = 'char' THEN 'string'                       
            WHEN DATA_TYPE = 'timestamp' THEN 'byte[]'
            WHEN DATA_TYPE = 'varbinary' THEN 'byte[]'
            WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'NO' THEN 'bool'
            WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'YES' THEN 'bool?'
            WHEN DATA_TYPE = 'xml' THEN 'string'
        END AS NewType
        FROM INFORMATION_SCHEMA.COLUMNS 
        WHERE TABLE_NAME = @tableName
        ORDER BY ORDINAL_POSITION
        ) AS a1 
    UNION 
    SELECT 3 as rowNr,  '} // class ' + @tableName
    ) as t Order By rowNr asc
END

P.S.:我本来想把它作为对他回答的修改建议提交,但我的经验是修改建议通常会被拒绝。

更新

用户chris-w-mclean提出了以下更改建议(请参见他的建议编辑),但我自己没有尝试:

  • SELECT 1 as rowNr, 'public class '替换为SELECT 1.0 as rowNr, 'public class '
  • SELECT 2 as rowNr, 'public '替换为SELECT 2 + a1.ORDINAL_POSITION/1000 as rowNr, 'public '
  • SELECT TOP 100 PERCENT COLUMN_NAME,替换为SELECT COLUMN_NAME,
  • IS_NULLABLE,CASE之间添加这一行:cast(ORDINAL_POSITION as float) as ORDINAL_POSITION,
  • 删除ORDER BY ORDINAL_POSITION
  • SELECT 3 as更改为SELECT 3.0 as

这段代码不能保证正确的排序 - 排序在联合本身中丢失了。ORDINAL_POSITION 应该通过查询进行提升,以便最终使用 ORDER BY rowNr, pos 进行排序。然后 "TOP 100 PERCENT" 的修补也可以去掉了。 - user2864740
当 DATA_TYPE = 'uniqueidentifier' 且 IS_NULLABLE = 'NO' 时,返回 'Guid' 当 DATA_TYPE = 'uniqueidentifier' 且 IS_NULLABLE = 'YES' 时,返回 'Guid?' - Igor Golodnitsky

6
请尝试这个我进行了优化的版本,所以结果不需要通过文本输出进行传递。相反,PRINT语句允许轻松地复制/粘贴输出。我还删除了子查询并添加了nvarchar / ntext类型的声明。
这是针对单个表的,但可以将其转换为存储过程以使用上面提到的其中一个游标建议。
SET NOCOUNT ON
DECLARE @tbl as varchar(255)
SET @tbl = '@@@@'

DECLARE @flds as varchar(8000)
SET @flds=''

SELECT -1 as f0, 'public class ' + @tbl + ' {' as f1 into #tmp

INSERT #tmp
SELECT 
    ORDINAL_POSITION, 
    '    public ' + 
    CASE 
        WHEN DATA_TYPE = 'varchar' THEN 'string'
        WHEN DATA_TYPE = 'nvarchar' THEN 'string'
        WHEN DATA_TYPE = 'text' THEN 'string'
        WHEN DATA_TYPE = 'ntext' THEN 'string'
        WHEN DATA_TYPE = 'char' THEN 'string'
        WHEN DATA_TYPE = 'xml' THEN 'string'
        WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'NO' THEN 'DateTime'
        WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'YES' THEN 'DateTime?'
        WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'YES' THEN 'int?'
        WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'NO' THEN 'int'
        WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'NO' THEN 'Int16'
        WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'YES' THEN 'Int16?'
        WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'NO' THEN 'decimal'
        WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'YES' THEN 'decimal?'
        WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'NO' THEN 'decimal'
        WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'YES' THEN 'decimal?'
        WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'NO' THEN 'decimal'
        WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'YES' THEN 'decimal?'
        WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'NO' THEN 'long'
        WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'YES' THEN 'long?'
        WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'NO' THEN 'byte'
        WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'YES' THEN 'byte?'
        WHEN DATA_TYPE = 'timestamp' THEN 'byte[]'
        WHEN DATA_TYPE = 'varbinary' THEN 'byte[]'
        WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'NO' THEN 'bool'
        WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'YES' THEN 'bool?'
    END + ' ' + COLUMN_NAME + ' {get;set;}'
FROM INFORMATION_SCHEMA.COLUMNS 
        WHERE TABLE_NAME = @tbl

INSERT #tmp SELECT 999, '}'

SELECT @flds=@flds + f1 +'
' from #tmp order by f0

DROP TABLE #tmp

PRINT @flds

4
我的方法是:
  1. 使用<dynamic>获取一些未分类的行
  2. 将这些行序列化为JSON格式
  3. 从控制台(或使用调试器)中复制JSON字符串
  4. 将其粘贴到JSON转换为C#模型生成器中(例如:https://app.quicktype.io/)。
即:
var persons = connection.Query<dynamic>("SELECT * FROM Persons");
var serializedPerson = JsonConvert.Serialize(persons.First());
Console.WriteLine(serializedPerson);

3

这个是给Oracle的。可能还不完整,但到目前为止对我来说都有效。

SELECT 
'public ' || A.NewType || ' ' || REPLACE(INITCAP(REPLACE(A.COLUMN_NAME, '_', ' ')), ' ', '') || ' {get;set;}' GET_SET
, A.*
 FROM 
(
SELECT
COLUMN_NAME,
DATA_TYPE,
NULLABLE,
CASE 
    WHEN DATA_TYPE = 'VARCHAR2' THEN 'string'
    WHEN DATA_TYPE = 'VARCHAR' THEN 'string'
    WHEN DATA_TYPE = 'DATE' AND NULLABLE = 'N' THEN 'DateTime'
    WHEN DATA_TYPE = 'DATE' AND NULLABLE = 'Y' THEN 'DateTime?'
    WHEN DATA_TYPE = 'INT' AND NULLABLE = 'N' THEN 'int?'
    WHEN DATA_TYPE = 'INT' AND NULLABLE = 'Y' THEN 'int'
    WHEN DATA_TYPE = 'DECIMAL' AND NULLABLE = 'N' THEN 'decimal'
    WHEN DATA_TYPE = 'DECIMAL' AND NULLABLE = 'Y' THEN 'decimal?'
    WHEN DATA_TYPE = 'NUMBER' AND NULLABLE = 'N' THEN 'decimal'
    WHEN DATA_TYPE = 'NUMBER' AND NULLABLE = 'Y' THEN 'decimal?'
    WHEN DATA_TYPE = 'NUMBER2' AND NULLABLE = 'N' THEN 'decimal'
    WHEN DATA_TYPE = 'NUMBER2' AND NULLABLE = 'Y' THEN 'decimal?'
    WHEN DATA_TYPE = 'CHAR' THEN 'string'
    WHEN DATA_TYPE = 'CHAR2' THEN 'string'
    WHEN DATA_TYPE = 'timestamp' THEN 'byte[]'
    WHEN DATA_TYPE = 'CLOB' THEN 'byte[]'
    ELSE '??'
END AS NewType
FROM USER_TAB_COLUMNS
WHERE TABLE_NAME = '<<TABLENAME>>'
ORDER BY COLUMN_ID
) A

2
这是我为了生成Dapper的POCOs而制作的dapper-pocos。该解决方案使用SQL Server的“sp_HELP”和“sp_describe_first_result_set”。将存储过程的名称或选择语句传递给它,它会生成与Dapper一起使用的相关POCO。该应用程序只是将存储过程或选择语句传递给sp_Help和sp_describe_first_result_set,并将结果映射到C#数据类型。请注意保留HTML标签。

2
我知道这是一个老话题,但还有另一个简单的选择可供选择。
你可以使用PocoClassGenerator: Mini Dapper's POCO Class Generator (支持Dapper Contrib)
  • 支持当前数据库中所有表和视图生成POCO类代码
  • 支持Dapper.Contrib
  • 支持多个RDBMS: sqlserver,oracle,mysql,postgresql
  • 小巧快速(只需5秒即可生成100个表的代码)
  • 对于每个数据库查询使用适当的方言模式表SQL

演示

20190430141947-image.png

开始

第一步:将PocoClassGenerator.cs代码复制并粘贴到您的项目或LINQPad中。
或者从NuGet安装。

PM> install-package PocoClassGenerator

第二步:使用 Connection 调用 GenerateAllTables 方法,然后打印输出结果。
using (var connection = Connection)
{
    Console.WriteLine(connection.GenerateAllTables());
}

只需使用 GeneratorBehavior.DapperContrib 调用方法。
using (var conn = GetConnection())
{
    var result = conn.GenerateAllTables(GeneratorBehavior.DapperContrib);
    Console.WriteLine(result);
}

在线演示:POCO Dapper Contrib类生成器GenerateAllTables | .NET Fiddle 20190502132948-image.png
using (var conn = GetConnection())
{
    var result = conn.GenerateAllTables(GeneratorBehavior.Comment);
    Console.WriteLine(result);
}

using (var conn = GetConnection())
{
    var result = conn.GenerateAllTables(GeneratorBehavior.View);
    Console.WriteLine(result);
}

using (var conn = GetConnection())
{
    var result = conn.GenerateAllTables(GeneratorBehavior.View | GeneratorBehavior.Comment | GeneratorBehavior.DapperContrib);
    Console.WriteLine(result);
}

生成一个类。
using (var connection = Connection)
{
    var classCode = connection.GenerateClass("select * from Table");
    Console.WriteLine(classCode);
}

2. 指定类名。
using (var connection = Connection)
{
    var classCode = connection.GenerateClass("with EMP as (select 1 ID,'WeiHan' Name,25 Age) select * from EMP", className: "EMP");
    Console.WriteLine(classCode);
}

DataTablePocoClassGenerator.cs 中的代码。
var dt = new DataTable();
dt.TableName = "TestTable";
dt.Columns.Add(new DataColumn() { ColumnName = "ID", DataType = typeof(string) });

var result = dt.GenerateClass();
var expect =
@"public class TestTable
{
public string ID { get; set; }
}";
Assert.Equal(expect, result);

1
这可能不适用于VS2010,但如果您一直在更新您的版本,那么这应该可以工作。
我生成数据库模型的方式是使用Ef Core Power Tools,它是一个小插件,使用Ef Core 6。
进入Visual Studio中的扩展并安装它。之后,您可以右键单击您的项目,在EF Core Power Tools下选择“反向工程”。 enter image description here 从那里,您连接到数据库,选择要反向工程的表,并选择“仅实体类型”。 您可以尽可能地具体,例如指定输出路径(在我的情况下为DbModels)。单击“确定”。

enter image description here

然后,您的模型应该弹出,您可以在Dapper-Code中自由使用这些模型。

1
我看到有人使用混合项目,使用EF来生成数据库,但是我必须对此进行dapper化处理。对于推荐的工具,我相信它们很好,但在尝试编写自己的解决方案之前,我会避免安装特殊软件。
话虽如此,这里有一个小型CLI程序(适用于我的需求),可能会有用。免责声明,我不是经验丰富的C#程序员,所以请原谅任何可能存在的偏差。
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using Dapper;

namespace Pocos
{
    public class TAB {
        public string TABLE_NAME { get; set; }
    }
    public class COL {
        public string COLUMN_NAME { get; set; }
        public int? ORIDINAL_POSITIONS { set; get; }
        public string DATA_TYPE { get; set; }
        public string CHARACTER_MAXIMUM_LENGTH { get; set; }
        public string NUMERIC_PRECISION { get; set; }
        public string NUMERIC_SCALE { get; set; }
    }
    class Program {
        static void Main(string[] args) {
            string sConnect = "Server=LT6-MARKL;Database=PKDEM815;UID=PKDEM815;Password=PKDEM815";
            IEnumerable tables;
            IEnumerable columns;
            List lines;
            using ( var conn = new SqlConnection(sConnect))
                tables = conn.Query("SELECT * FROM INFORMATION_SCHEMA.TABLES ORDER BY TABLE_NAME");
            // Roll through each table of the database and generate an .cs file, as a POCO
            foreach (TAB t in tables.OrderBy(t => t.TABLE_NAME)) {
                lines = new List();
                lines.Add("using System;");
                lines.Add("using System.Collections.Generic;");
                lines.Add("using System.Configuration;");
                lines.Add("using System.Data.SqlClient;");
                lines.Add("using Dapper;"); 
                lines.Add("using Dapper.Contrib.Extensions;");
                lines.Add("");
                lines.Add("namespace PKDataLayer.Models  {");
                lines.Add("");
                lines.Add("\t[Table(\"" + t.TABLE_NAME + "\")]");
                lines.Add("\tpublic class " + t.TABLE_NAME + " {");
                lines.Add("");
                using (var conn2 = new SqlConnection(sConnect)) {
                    columns = conn2.Query("SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = '"+ t.TABLE_NAME +"' ORDER BY ORDINAL_POSITION");
                    foreach( COL c in columns) {
                        if (t.TABLE_NAME + "_KEY" == c.COLUMN_NAME || t.TABLE_NAME + "_SEQNUM" == c.COLUMN_NAME)
                            lines.Add("\t\t[Key]");
                        // SELECT DISTINCT DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME IN ( SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES )
                        if (c.DATA_TYPE == "char" || c.DATA_TYPE == "varchar")
                            lines.Add("\t\tpublic string " + c.COLUMN_NAME + " { get; set; }");
                        if (c.DATA_TYPE == "int")
                            lines.Add("\t\tpublic int " + c.COLUMN_NAME + " { get; set; }");
                        if (c.DATA_TYPE == "datetime")
                            lines.Add("\t\tpublic DateTime? " + c.COLUMN_NAME + " { get; set; }");
                        if (c.DATA_TYPE == "decimal" || c.DATA_TYPE == "numeric")
                            lines.Add("\t\tpublic decimal? " + c.COLUMN_NAME + " { get; set; }");
                    }
                }
                lines.Add("\t}");
                lines.Add("}");
                Console.WriteLine("Creating POCO for " + t.TABLE_NAME);
                using (TextWriter tw = new StreamWriter( t.TABLE_NAME + ".cs" ))
                    foreach (String s in lines)
                        tw.WriteLine(s);
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接