【问题标题】:How to generate model from database using Dapper?如何使用 Dapper 从数据库生成模型?
【发布时间】:2012-06-15 18:18:41
【问题描述】:

我来自 PetaPoco 营地。 PetaPoco 有一个从数据库生成模型的 T4 模板。 Dapper 有类似的东西吗?

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

【问题讨论】:

    标签: visual-studio-2010 dapper micro-orm


    【解决方案1】:

    我最近刚刚编写了一个 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
    

    【讨论】:

    • 我喜欢这个小脚本。如果您想要从现有表中生成快速而肮脏的 POCO,没有比这更容易的了。如果您需要映射更多字段,请使用此链接查找它们。 msdn.microsoft.com/en-us/library/ms131092.aspx
    • 不要忘记 WHEN DATA_TYPE = 'nvarchar' THEN 'string'
    • 我添加了这两行 WHEN DATA_TYPE = 'nvarchar' THEN 'string' WHEN DATA_TYPE = 'uniqueidentifier' THEN 'Guid'
    • 当 DATA_TYPE LIKE '%char%' THEN 'string'
    • 对不起,我不擅长 SQL。但是你能给出如何在 Dapper for C# lang 中使用它的示例代码吗?
    【解决方案2】:

    从游标调用存储过程

    如果你结合提到的 sp 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
    

    提到的存储过程matritchies

    我从 matritchies 的答案(见上文)中获取了 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 提出了以下我自己没有尝试过的更改(参见his suggested-edit):

    • 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”组合也可以去。
    • 当 DATA_TYPE = 'uniqueidentifier' AND IS_NULLABLE = 'NO' THEN 'Guid' WHEN DATA_TYPE = 'uniqueidentifier' AND IS_NULLABLE = 'YES' THEN 'Guid?'
    【解决方案3】:

    试试这个我优化了一点的版本,所以结果不需要通过管道传输到文本输出。相反,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】:

      Dapper 本身为连接对象提供了一些扩展方法(查询、执行),并且没有“模型生成器”。也许可以使用其他一些框架来生成基于 db 模式的 POCO。

      更新:

      Database tables to C# POCO classes T4 template

      <#@ 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;
                  }
      
      
      
              }
      #>
      

      【讨论】:

      【解决方案5】:

      这是dapper-pocos 我为 Dapper 生成 POCO 而制作的。该解决方案使用 SQL Server 的“sp_HELP”和“sp_describe_first_result_set”。给它一个存储过程的名称,或者给它一个 select 语句,它会生成相关的 POCO 用于 Dapper。应用程序只是将存储过程或 select 语句传递给 sp_Help 和 sp_describe_first_result_set,并将结果映射到 C# 数据类型。

      【讨论】:

        【解决方案6】:

        我的方法是:

        1. 使用&lt;dynamic&gt; 获取一些没有类型的行
        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);
        

        【讨论】:

          【解决方案7】:

          这个是给甲骨文的。它可能不完整,但到目前为止它对我有用。

          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 = 'FIN_GLOBAL_CR_NUM_A'
          ORDER BY COLUMN_ID
          ) A
          

          【讨论】:

            【解决方案8】:

            我知道这是一个老话题,但还有一个简单的选项可以选择。

            您可以使用PocoClassGenerator: Mini Dapper's POCO Class Generator (Support Dapper Contrib)

            • 支持当前DataBase所有表和视图生成POCO类代码
            • 支持Dapper.Contrib
            • 支持多个RDBMS:sqlserver,oracle,mysql,postgresql
            • 迷你和更快(仅在 5 秒内生成 100 表代码)
            • 为每个数据库查询使用适当的方言架构表 SQL

            演示

            开始

            ?首先:将 PocoClassGenerator.cs 代码复制并粘贴到您的项目或 LINQPad。
            或从NuGet安装

            PM> install-package PocoClassGenerator
            

            ?第二个:使用Connection调用GenerateAllTables然后打印出来。

            using (var connection = Connection)
            {
                Console.WriteLine(connection.GenerateAllTables());
            }
            
            支持 Dapper Contrib POCO 类
            • 只需用GeneratorBehavior.DapperContrib调用方法
            using (var conn = GetConnection())
            {
                var result = conn.GenerateAllTables(GeneratorBehavior.DapperContrib);
                Console.WriteLine(result);
            }
            

            在线演示:POCO Dapper Contrib Class Generator GenerateAllTables | .NET Fiddle

            生成评论
            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);
            }
            
            生成视图和评论以及 Dapper.Contrib
            using (var conn = GetConnection())
            {
                var result = conn.GenerateAllTables(GeneratorBehavior.View | GeneratorBehavior.Comment | GeneratorBehavior.DapperContrib);
                Console.WriteLine(result);
            }
            
            通过sql生成一个类
            1. 生成一个类
            using (var connection = Connection)
            {
                var classCode = connection.GenerateClass("select * from Table");
                Console.WriteLine(classCode);
            }
            
            1. 指定类名
            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);
            }
            
            数据表PocoClass

            代码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);
            

            【讨论】:

              【解决方案9】:

              我是名为 CodegenCS.POCO 的 POCO-Generator 模板的作者。

              上面的链接包含 C# 和 PowerShell 脚本,它们允许您构建完整的 POCO(准备在 Dapper 中使用),其中还包括 override bool Equals()override int GetHashCode(),并且(对于喜欢它的人)它包括完整的 ActiveRecord CRUD 查询(插入/更新)。

              从 Northwind 数据库中查看 example POCO。如果你喜欢它,使用模板非常容易:

              generator script 非常易于理解和自定义。

              【讨论】:

                【解决方案10】:

                我有完全相同的要求,即从数据库生成对象,同时在 Dapper 中可靠有效地处理 CRUD,并采用不同的方法准备替换 Dapper 自己的 Dapper.Contrib 并支持实体框架模式定义,以便为数据库搭建脚手架(模型、关系、键)可以使用实体框架工具来完成,例如here,示例如下:

                dotnet add package Microsoft.EntityFrameworkCore.SqlServer
                dotnet add package Microsoft.EntityFrameworkCore.Design
                dotnet ef dbcontext scaffold "Server=.\;Database=AdventureWorksLT2012;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -o Model
                

                搭建脚手架后可以从项目中移除以上依赖。

                目前Dapper.SqlGenerator 已成功投入生产。就性能而言,它不会比 Dapper 产生任何开销,有时会减少通过其他方式生成查询的时间。

                请记住,有 2 个单独的 nuget 包 - Dapper.SqlGenerator 用于从 EF(Core)脚手架模型生成纯 SQL 代码,Dapper.SqlGenerator.Async 用于使用 Dapper 对数据库运行 CRUD 查询。

                TLDR;您可以使用 Entity Framework (Core) 从数据库构建模型,并使用 Dapper.SqlGenerator 对生成的对象生成 CRUD 查询。

                【讨论】:

                  【解决方案11】:

                  我已经看到人们在哪里使用混合项目,使用 EF 来搭建数据库,但我不得不对其中的输出进行精简。对于推荐的工具,我确信它们很好,但我不愿安装特殊软件,直到我尝试编写自己的解决方案。

                  也就是说,这是一个可能有用的小型 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);
                              }
                          }
                      }
                  }

                  【讨论】:

                    猜你喜欢
                    • 2012-07-01
                    • 1970-01-01
                    • 2011-08-20
                    • 2018-12-12
                    • 2011-02-23
                    • 1970-01-01
                    • 1970-01-01
                    • 2021-04-13
                    • 1970-01-01
                    相关资源
                    最近更新 更多