【问题标题】:Generate class from database table从数据库表生成类
【发布时间】:2011-08-17 21:46:15
【问题描述】:

如何从 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 |
+----+-------+----------------+


【问题讨论】:

  • 为什么不让 Entity Framework 为您生成类,而只是不使用与数据库访问有关的类?
  • 我完全同意@John Saunders。过去我自己手动完成,但这太耗时了。在大多数情况下,EF 只是第一次就做对了。如果没有,调整生成的类比自己做所有的时间要少得多。我的时间比编写 ORM 生成器可以为我做的代码更好。我知道我不喜欢生成的代码,但在时间(和成本)节省上的权衡是值得的,至少对我来说是这样。
  • 我认为 EF 确实是最好的解决方案。另一种可能性是 LINQ to sql 类。您只需将其添加到您的项目中并为其提供数据库连接。接下来,您只需选择您需要的表格,它就会为您制作一些课程。
  • 在实践中,EF 并不总是在任何情况下都是最佳解决方案。例如,可能有几个没有经验的开发人员对 edmx 文件进行粗暴的更改,这至少会导致版本冲突……此外,该选项也可能并不总是可用。例如,技术主管可能出于某种原因根本不希望您使用它。

标签: c# sql sql-server tsql


【解决方案1】:

将@TableName 设置为您的表的名称。

declare @TableName sysname = 'TableName'
declare @Result varchar(max) = 'public class ' + @TableName + '
{'

select @Result = @Result + '
    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  + '
}'

print @Result

【讨论】:

  • 对于 Nullable 类型,在 Alex 的 SQL 脚本中将此代码附加在 endColumnType 之间。 + CASE WHEN col.is_nullable=1 AND typ.name NOT IN ('binary', 'varbinary', 'image', 'text', 'ntext', 'varchar', 'nvarchar', 'char', 'nchar') THEN '?' ELSE '' END
  • @AlexAza 你应该把“when 'float' then 'float'”改成“when 'float' then 'double'”,你应该把“when 'real' then 'double'”改成“when 'real' then 'float'”。看来你把这些类型弄糊涂了。相当于 SQL 浮点数的 C# 是双精度数,相当于 SQL 实数的 C# 是浮点数。
  • 不错的答案,但您需要将 print @Result 更改为 print CAST(@Result AS TEXT) 否则它会在大表上被截断。
  • 如何添加数据注释进行验证 - 例如最大字段长度? :)
  • 我已经为output all tables of a database as POCOs/models 派生了一个版本。
【解决方案2】:

我无法得到 Alex 在 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
    }

}

使用EF、Linq to Sql、甚至Scaffolding可能是个思路;然而,有时像这样的一段代码会派上用场。坦率地说,我不喜欢使用 EF 导航属性,因为它生成的代码进行了 19,200 次单独的数据库调用来填充 1000 行网格。这可以在单个数据库调用中实现。尽管如此,可能只是您的技术架构师不希望您使用 EF 等。所以,你必须恢复到这样的代码......顺便说一句,用 DataAnnotations 等属性装饰每个属性也可能是一个想法,但我严格遵守 POCO。

编辑 TimeStampGuid?

已修复

【讨论】:

  • +1,这对我也很有效。我将 EF 用于我们的主数据库,但需要从另一个数据库中获取一个存储过程,并且不想为此编写整个 EF 项目,所以这让我可以快速创建一个类来容纳我的存储过程结果集...谢谢
  • 我现在仍在使用它,但我已经包含了字符串长度等的 MVC 属性属性。
  • 为我生成没有属性/列的空类。
  • @highwingers:您使用的是有效的模式和表名吗?请向我展示您对上述内容的实现。
  • 这是抛光的。我正在使用这个。但感谢 Alex 创建了原始版本。
【解决方案3】:

VB版

declare @TableName sysname = 'myTableName'
declare @prop varchar(max)
PRINT 'Public Class ' + @TableName
declare props cursor for
select distinct ' public property ' + ColumnName + ' AS ' + ColumnType AS prop
from ( 
    select  
        replace(col.name, ' ', '_') ColumnName,  column_id, 
        case typ.name  
            when 'bigint' then 'long' 
            when 'binary' then 'byte[]' 
            when 'bit' then 'boolean' 
            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 'float' 
            when 'image' then 'byte[]' 
            when 'int' then 'integer' 
            when 'money' then 'decimal' 
            when 'nchar' then 'char' 
            when 'ntext' then 'string' 
            when 'numeric' then 'decimal' 
            when 'nvarchar' then 'string' 
            when 'real' then 'double' 
            when 'smalldatetime' then 'DateTime' 
            when 'smallint' then 'short' 
            when 'smallmoney' then 'decimal' 
            when 'text' then 'string' 
            when 'time' then 'TimeSpan' 
            when 'timestamp' then 'DateTime' 
            when 'tinyint' then 'byte' 
            when 'uniqueidentifier' then 'Guid' 
            when 'varbinary' then 'byte[]' 
            when 'varchar' then 'string' 
        end ColumnType 
    from sys.columns col join sys.types typ on col.system_type_id = typ.system_type_id 
    where object_id = object_id(@TableName) 
) t 
order by prop
open props
FETCH NEXT FROM props INTO @prop
WHILE @@FETCH_STATUS = 0
BEGIN
    print @prop
    FETCH NEXT FROM props INTO @prop
END
close props
DEALLOCATE props
PRINT 'End Class'

【讨论】:

  • @highwingers 自 Visual Studio 2010 以来,它们不是必需的 stackoverflow.com/a/460032/618186
  • 我必须在顶部添加“使用 MyDatabase”文本才能正常工作。否则它会生成一些无法识别的类属性。
  • 非常好。但是float应该去Doublebyte[]Byte()
  • 做得很好。我什至尝试了一个视图,它就像一个魅力!
【解决方案4】:

有点晚了,但我创建了一个网络工具来帮助从 SQL 结果、SQL 表和 SQL SP 创建 C#(或其他)对象。

sql2object.com

这确实可以确保您不必键入所有属性和类型。

如果无法识别类型,将选择默认类型。

【讨论】:

  • 不错但是不能使用表定义脚本作为源
  • 这很棒 :) 它对结果和表格都有效,这很棒。如果您可以修改它以忽略所有 CREATE TABLE 内容,这样我就可以剪切和粘贴所有内容,那就太好了。此外,如果你有机会可以在其中添加一个“Trim()” - 如果开头有一个空行,那么它会失败,然后人们会放弃它。如果您知道将其删除,这很简单 - 但是当您出错时,您会失去人。
  • 还有什么是 SQL 结果集的格式。我只是从文本输出窗口复制和粘贴,它给了我一个包含所有列名的字段:-/ 有什么诀窍?
  • 或者您可以将其开源,让社区按照他们想要的方式构建它。
  • 它不会从“Create Table”脚本创建 C# 类,
【解决方案5】:

我想给我的 2 美分

0) 查询优先 https://marketplace.visualstudio.com/items?itemName=bbsimonbb.QueryFirst Query-first 是一个 Visual Studio 扩展,用于在 C# 项目中智能地使用 SQL。使用提供的 .sql 模板来开发您的查询。当您保存文件时,Query-first 运行您的查询,检索架构并生成两个类和一个接口:一个具有 Execute()、ExecuteScalar()、ExecuteNonQuery() 等方法的包装类,其对应的接口和一个 POCO 封装一行结果。

1) Sql2Objects 从查询结果开始创建类(但不是 DAL)

2) https://docs.microsoft.com/en-us/ef/ef6/resources/tools

3) https://visualstudiomagazine.com/articles/2012/12/11/sqlqueryresults-code-generation.aspx

4) http://www.codesmithtools.com/product/generator#features

【讨论】:

    【解决方案6】:

    要打印出 NULLABLE 属性,请使用这个。
    它对 Alex Aza 的 CASE 语句块脚本进行了轻微修改。

    declare @TableName sysname = 'TableName'
    declare @result varchar(max) = 'public class ' + @TableName + '
    {'
    
    select @result = @result + '
        public ' + ColumnType + ' ' + ColumnName + ' { get; set; }
    '
    from
    (
        select 
            replace(col.name, ' ', '_') ColumnName,
            column_id,
            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 'float'
                when 'image' then 'byte[]'
                when 'int' then 'int'
                when 'money' then 'decimal'
                when 'nchar' then 'char'
                when 'ntext' then 'string'
                when 'numeric' then 'decimal'
                when 'nvarchar' then 'string'
                when 'real' then 'double'
                when 'smalldatetime' then 'DateTime'
                when 'smallint' then 'short'
                when 'smallmoney' then 'decimal'
                when 'text' then 'string'
                when 'time' then 'TimeSpan'
                when 'timestamp' then 'DateTime'
                when 'tinyint' then 'byte'
                when 'uniqueidentifier' then 'Guid'
                when 'varbinary' then 'byte[]'
                when 'varchar' then 'string'
                else 'UNKNOWN_' + typ.name
            end + 
            CASE
                WHEN col.is_nullable=1 AND
                     typ.name NOT IN (
                         'binary', 'varbinary', 'image',
                         'text', 'ntext',
                         'varchar', 'nvarchar', 'char', 'nchar')
                THEN '?'
                ELSE '' END AS [ColumnType]
        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 column_id
    
    set @result = @result  + '
    }'
    
    print @result
    

    【讨论】:

      【解决方案7】:

      是的,如果您使用像 Dapper 这样的简单 ORM,这些都很棒。

      如果您使用 .Net,您可以在运行时使用 WriteXmlSchema 方法使用任何 DataSet 生成 XSD 文件。 http://msdn.microsoft.com/en-us/library/xt7k72x8(v=vs.110).aspx

      像这样:

      using (SqlConnection cnn = new SqlConnection(mConnStr)) {
      DataSet Data = new DataSet();
      cnn.Open();
      string sql = "SELECT * FROM Person";
      
      using (SqlDataAdapter Da = new SqlDataAdapter(sql, cnn))
      {
      try
      {
          Da.Fill(Data);
          Da.TableMappings.Add("Table", "Person");
          Data.WriteXmlSchema(@"C:\Person.xsd");
      }
      catch (Exception ex)
      { MessageBox.Show(ex.Message); }
      }
      cnn.Close();
      

      从那里您可以使用 xsd.exe 创建一个可从开发人员命令提示符进行 XML 序列化的类。 http://msdn.microsoft.com/en-us/library/x6c1kb0s(v=vs.110).aspx

      像这样:

      xsd C:\Person.xsd /classes /language:CS
      

      【讨论】:

        【解决方案8】:

        如果您有权访问 SQL Server 2016,则可以使用 FOR JSON(带有 INCLUDE_NULL_VALUES)选项从 select 语句中获取 JSON 输出。复制输出,然后在 Visual Studio 中粘贴特殊 -> 将 JSON 粘贴为类。

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

        【讨论】:

          【解决方案9】:

          我尝试使用上述建议,并在此过程中改进了此线程中的解决方案。

          假设您使用实现 PropertyChanged 事件的基类(在本例中为 ObservableObject),您将执行类似的操作。有一天我可能会在我的博客上写一篇博文 sqljana.wordpress.com

          请用值替换前三个变量:

              --These three things have to be substituted (when called from Powershell, they are replaced before execution)
          DECLARE @Schema VARCHAR(MAX) = N'&Schema'
          DECLARE @TableName VARCHAR(MAX) = N'&TableName'
          DECLARE @Namespace VARCHAR(MAX) = N'&Namespace'
          
          DECLARE @CRLF VARCHAR(2) = CHAR(13) + CHAR(10);
          DECLARE @result VARCHAR(max) = ' '
          
          DECLARE @PrivateProp VARCHAR(100) = @CRLF + 
                          CHAR(9) + CHAR(9) + 'private <ColumnType> _<ColumnName>;';
          DECLARE @PublicProp VARCHAR(255) = @CRLF + 
                          CHAR(9) + CHAR(9) + 'public <ColumnType> <ColumnName> '  + @CRLF +
                          CHAR(9) + CHAR(9) + '{ ' + @CRLF +
                          CHAR(9) + CHAR(9) + '   get { return _<ColumnName>; } ' + @CRLF +
                          CHAR(9) + CHAR(9) + '   set ' + @CRLF +
                          CHAR(9) + CHAR(9) + '   { ' + @CRLF +
                          CHAR(9) + CHAR(9) + '       _<ColumnName> = value;' + @CRLF +
                          CHAR(9) + CHAR(9) + '       base.RaisePropertyChanged();' + @CRLF +
                          CHAR(9) + CHAR(9) + '   } ' + @CRLF +
                          CHAR(9) + CHAR(9) + '}' + @CRLF;
          
          DECLARE @RPCProc VARCHAR(MAX) = @CRLF +         
                          CHAR(9) + CHAR(9) + 'public event PropertyChangedEventHandler PropertyChanged; ' + @CRLF +
                          CHAR(9) + CHAR(9) + 'private void RaisePropertyChanged( ' + @CRLF +
                          CHAR(9) + CHAR(9) + '       [CallerMemberName] string caller = "" ) ' + @CRLF +
                          CHAR(9) + CHAR(9) + '{  ' + @CRLF +
                          CHAR(9) + CHAR(9) + '   if (PropertyChanged != null)  ' + @CRLF +
                          CHAR(9) + CHAR(9) + '   { ' + @CRLF +
                          CHAR(9) + CHAR(9) + '       PropertyChanged( this, new PropertyChangedEventArgs( caller ) );  ' + @CRLF +
                          CHAR(9) + CHAR(9) + '   } ' + @CRLF +
                          CHAR(9) + CHAR(9) + '}';
          
          DECLARE @PropChanged VARCHAR(200) =  @CRLF +            
                          CHAR(9) + CHAR(9) + 'protected override void AfterPropertyChanged(string propertyName) ' + @CRLF +
                          CHAR(9) + CHAR(9) + '{ ' + @CRLF +
                          CHAR(9) + CHAR(9) + '   System.Diagnostics.Debug.WriteLine("' + @TableName + ' property changed: " + propertyName); ' + @CRLF +
                          CHAR(9) + CHAR(9) + '}';
          
          SET @result = 'using System;' + @CRLF + @CRLF +
                          'using MyCompany.Business;' + @CRLF + @CRLF +
                          'namespace ' + @Namespace  + @CRLF + '{' + @CRLF +
                          '   public class ' + @TableName + ' : ObservableObject' + @CRLF + 
                          '   {' + @CRLF +
                          '   #region Instance Properties' + @CRLF 
          
          SELECT @result = @result
                           + 
                          REPLACE(
                                      REPLACE(@PrivateProp
                                      , '<ColumnName>', ColumnName)
                                  , '<ColumnType>', ColumnType)
                          +                           
                          REPLACE(
                                      REPLACE(@PublicProp
                                      , '<ColumnName>', ColumnName)
                                  , '<ColumnType>', ColumnType)                   
          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 'Boolean?' ELSE 'Boolean' 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 'Int32?' ELSE 'Int32' 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 
                          CASE C.IS_NULLABLE
                              WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                                    
                      WHEN 'tinyint' THEN 
                          CASE C.IS_NULLABLE
                              WHEN 'YES' THEN 'Byte?' ELSE 'Byte' END                                                
                      WHEN 'uniqueidentifier' THEN 'Guid'
                      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(@Schema, c.TABLE_SCHEMA) = c.TABLE_SCHEMA  
          ) t
          ORDER BY t.ORDINAL_POSITION
          
          SELECT @result = @result + @CRLF + 
                          CHAR(9) + '#endregion Instance Properties' + @CRLF +
                          --CHAR(9) + @RPCProc + @CRLF +
                          CHAR(9) + @PropChanged + @CRLF +
                          CHAR(9) + '}' + @CRLF +
                          @CRLF + '}' 
          --SELECT @result
          PRINT @result
          

          基类基于 Josh Smith 在此处的文章 来自http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/

          我确实将类重命名为 ObservableObject,并且还利用了 c# 5 的 CallerMemberName 属性特性

          //From http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/
          //
          //Jana's change: Used c# 5 feature to bypass passing in the property name using [CallerMemberName] 
          //  protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
          
          using System;
          using System.Collections.Generic;
          using System.ComponentModel;
          using System.Diagnostics;
          using System.Reflection;
          using System.Runtime.CompilerServices;
          
          namespace MyCompany.Business
          {
          
              /// <summary>
              /// Implements the INotifyPropertyChanged interface and 
              /// exposes a RaisePropertyChanged method for derived 
              /// classes to raise the PropertyChange event.  The event 
              /// arguments created by this class are cached to prevent 
              /// managed heap fragmentation.
              /// </summary>
              [Serializable]
              public abstract class ObservableObject : INotifyPropertyChanged
              {
                  #region Data
          
                  private static readonly Dictionary<string, PropertyChangedEventArgs> eventArgCache;
                  private const string ERROR_MSG = "{0} is not a public property of {1}";
          
                  #endregion // Data
          
                  #region Constructors
          
                  static ObservableObject()
                  {
                      eventArgCache = new Dictionary<string, PropertyChangedEventArgs>();
                  }
          
                  protected ObservableObject()
                  {
                  }
          
                  #endregion // Constructors
          
                  #region Public Members
          
                  /// <summary>
                  /// Raised when a public property of this object is set.
                  /// </summary>
                  [field: NonSerialized]
                  public event PropertyChangedEventHandler PropertyChanged;
          
                  /// <summary>
                  /// Returns an instance of PropertyChangedEventArgs for 
                  /// the specified property name.
                  /// </summary>
                  /// <param name="propertyName">
                  /// The name of the property to create event args for.
                  /// </param>        
                  public static PropertyChangedEventArgs
                      GetPropertyChangedEventArgs(string propertyName)
                  {
                      if (String.IsNullOrEmpty(propertyName))
                          throw new ArgumentException(
                              "propertyName cannot be null or empty.");
          
                      PropertyChangedEventArgs args;
          
                      // Get the event args from the cache, creating them
                      // and adding to the cache if necessary.
                      lock (typeof(ObservableObject))
                      {
                          bool isCached = eventArgCache.ContainsKey(propertyName);
                          if (!isCached)
                          {
                              eventArgCache.Add(
                                  propertyName,
                                  new PropertyChangedEventArgs(propertyName));
                          }
          
                          args = eventArgCache[propertyName];
                      }
          
                      return args;
                  }
          
                  #endregion // Public Members
          
                  #region Protected Members
          
                  /// <summary>
                  /// Derived classes can override this method to
                  /// execute logic after a property is set. The 
                  /// base implementation does nothing.
                  /// </summary>
                  /// <param name="propertyName">
                  /// The property which was changed.
                  /// </param>
                  protected virtual void AfterPropertyChanged(string propertyName)
                  {
                  }
          
                  /// <summary>
                  /// Attempts to raise the PropertyChanged event, and 
                  /// invokes the virtual AfterPropertyChanged method, 
                  /// regardless of whether the event was raised or not.
                  /// </summary>
                  /// <param name="propertyName">
                  /// The property which was changed.
                  /// </param>
                  protected void RaisePropertyChanged([CallerMemberName] string propertyName = "")
                  {
                      this.VerifyProperty(propertyName);
          
                      PropertyChangedEventHandler handler = this.PropertyChanged;
                      if (handler != null)
                      {
                          // Get the cached event args.
                          PropertyChangedEventArgs args =
                              GetPropertyChangedEventArgs(propertyName);
          
                          // Raise the PropertyChanged event.
                          handler(this, args);
                      }
          
                      this.AfterPropertyChanged(propertyName);
                  }
          
                  #endregion // Protected Members
          
                  #region Private Helpers
          
                  [Conditional("DEBUG")]
                  private void VerifyProperty(string propertyName)
                  {
                      Type type = this.GetType();
          
                      // Look for a public property with the specified name.
                      PropertyInfo propInfo = type.GetProperty(propertyName);
          
                      if (propInfo == null)
                      {
                          // The property could not be found,
                          // so alert the developer of the problem.
          
                          string msg = string.Format(
                              ERROR_MSG,
                              propertyName,
                              type.FullName);
          
                          Debug.Fail(msg);
                      }
                  }
          
                  #endregion // Private Helpers
              }
          }
          

          这是你们会更喜欢的部分。我构建了一个 Powershell 脚本来为 SQL 数据库中的所有表生成。它基于一个名为 Chad Miller 的 Invoke-SQLCmd2 cmdlet 的 Powershell 大师,可以从这里下载: http://gallery.technet.microsoft.com/ScriptCenter/7985b7ef-ed89-4dfd-b02a-433cc4e30894/

          拥有该 cmdlet 后,为所有表生成的 Powershell 脚本就变得很简单(用您的特定值替换变量)。

          . C:\MyScripts\Invoke-Sqlcmd2.ps1
          
          $serverInstance = "MySQLInstance"
          $databaseName = "MyDb"
          $generatorSQLFile = "C:\MyScripts\ModelGen.sql" 
          $tableListSQL = "SELECT name FROM $databaseName.sys.tables"
          $outputFolder = "C:\MyScripts\Output\"
          $namespace = "MyCompany.Business"
          
          $placeHolderSchema = "&Schema"
          $placeHolderTableName = "&TableName"
          $placeHolderNamespace = "&Namespace"
          
          #Get the list of tables in the database to generate c# models for
          $tables = Invoke-Sqlcmd2 -ServerInstance $serverInstance -Database $databaseName -Query $tableListSQL -As DataRow -Verbose
          
          foreach ($table in $tables)
          {
              $table1 = $table[0]
              $outputFile = "$outputFolder\$table1.cs"
          
          
              #Replace variables with values (returns an array that we convert to a string to use as query)
              $generatorSQLFileWSubstitutions = (Get-Content $generatorSQLFile).
                                                      Replace($placeHolderSchema,"dbo").
                                                      Replace($placeHolderTableName, $table1).
                                                      Replace($placeHolderNamespace, $namespace) | Out-String
          
              "Ouputing for $table1 to $outputFile"
          
              #The command generates .cs file content for model using "PRINT" statements which then gets written to verbose output (stream 4)
              # ...capture the verbose output and redirect to a file
              (Invoke-Sqlcmd2 -ServerInstance $serverInstance -Database $databaseName -Query $generatorSQLFileWSubstitutions -Verbose) 4> $outputFile
          
          }
          

          【讨论】:

          • 自从我问这个问题已经 3 年多了,我现在不使用 sql 数据库(大数据、mongodb 等)。但我肯定会很快对此进行测试,您在阐述这个答案并为社区做出贡献时度过了愉快的时光。非常感谢!
          • 我已经使用 StackOverflow 很长时间了,但现在才开始贡献。所以,你可以说我开始学习 S.O.礼仪也是。当我在寻找这样的解决方案时,我偶然发现了这个线程并添加了我的扩展解决方案,以便未来的用户可以从中受益。感谢您的评论。
          • 谢谢。是否可以在 tsql 脚本中完成所有这些操作 - 而不是使用 powershell?
          【解决方案10】:

          使用模板创建自定义代码的过程

          create PROCEDURE [dbo].[createCode]
          (   
             @TableName sysname = '',
             @befor varchar(max)='public class  @TableName  
          {',
             @templet varchar(max)=' 
               public @ColumnType @ColumnName   { get; set; }  // @ColumnDesc  ',
             @after varchar(max)='
          }'
          
          )
          AS
          BEGIN 
          
          
          declare @result varchar(max)
          
          set @befor =replace(@befor,'@TableName',@TableName)
          
          set @result=@befor
          
          select @result = @result 
          + replace(replace(replace(replace(replace(@templet,'@ColumnType',ColumnType) ,'@ColumnName',ColumnName) ,'@ColumnDesc',ColumnDesc),'@ISPK',ISPK),'@max_length',max_length)
          
          from  
          (
              select 
              column_id,
              replace(col.name, ' ', '_') ColumnName,
              typ.name as sqltype,
              typ.max_length,
              is_identity,
              pkk.ISPK, 
                  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 'float'
                      when 'image' then 'byte[]'
                      when 'int' then 'int'
                      when 'money' then 'decimal'
                      when 'nchar' then 'char'
                      when 'ntext' then 'string'
                      when 'numeric' then 'decimal'
                      when 'nvarchar' then 'String'
                      when 'real' then 'double'
                      when 'smalldatetime' then 'DateTime'
                      when 'smallint' then 'short'
                      when 'smallmoney' then 'decimal'
                      when 'text' then 'String'
                      when 'time' then 'TimeSpan'
                      when 'timestamp' then 'DateTime'
                      when 'tinyint' then 'byte'
                      when 'uniqueidentifier' then 'Guid'
                      when 'varbinary' then 'byte[]'
                      when 'varchar' then 'string'
                      else 'UNKNOWN_' + typ.name
                  END + CASE WHEN col.is_nullable=1 AND typ.name NOT IN ('binary', 'varbinary', 'image', 'text', 'ntext', 'varchar', 'nvarchar', 'char', 'nchar') THEN '?' ELSE '' END ColumnType,
                isnull(colDesc.colDesc,'') AS ColumnDesc 
              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
                      left join
                      (
                          SELECT c.name  AS 'ColumnName', CASE WHEN dd.pk IS NULL THEN 'false' ELSE 'true' END ISPK           
                          FROM        sys.columns c
                              JOIN    sys.tables  t   ON c.object_id = t.object_id    
                              LEFT JOIN (SELECT   K.COLUMN_NAME , C.CONSTRAINT_TYPE as pk  
                                  FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K 
                                      LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C
                                  ON K.TABLE_NAME = C.TABLE_NAME
                                      AND K.CONSTRAINT_NAME = C.CONSTRAINT_NAME
                                      AND K.CONSTRAINT_CATALOG = C.CONSTRAINT_CATALOG
                                      AND K.CONSTRAINT_SCHEMA = C.CONSTRAINT_SCHEMA            
                                  WHERE K.TABLE_NAME = @TableName) as dd
                               ON dd.COLUMN_NAME = c.name
                           WHERE       t.name = @TableName       
                      ) pkk  on ColumnName=col.name
          
              OUTER APPLY (
              SELECT TOP 1 CAST(value AS NVARCHAR(max)) AS colDesc
              FROM
                 sys.extended_properties
              WHERE
                 major_id = col.object_id
                 AND
                 minor_id = COLUMNPROPERTY(major_id, col.name, 'ColumnId')
              ) colDesc      
              where object_id = object_id(@TableName)
          
              ) t
          
              set @result=@result+@after
          
              select @result
              --print @result
          
          END
          

          现在创建自定义代码

          例如 c# 类

          exec [createCode] @TableName='book',@templet =' 
               public @ColumnType @ColumnName   { get; set; }  // @ColumnDesc  '
          

          输出是

          public class  book  
          { 
               public long ID   { get; set; }  //    
               public String Title   { get; set; }  // Book Title  
          }
          

          对于 LINQ

          exec [createCode] @TableName='book'
          , @befor  ='[System.Data.Linq.Mapping.Table(Name = "@TableName")]
          public class @TableName
          {',
          
             @templet  =' 
               [System.Data.Linq.Mapping.Column(Name = "@ColumnName", IsPrimaryKey = @ISPK)]
               public @ColumnType @ColumnName   { get; set; }  // @ColumnDesc  
               ' ,
          
             @after  ='
          }'
          

          输出是

          [System.Data.Linq.Mapping.Table(Name = "book")]
          public class book
          { 
               [System.Data.Linq.Mapping.Column(Name = "ID", IsPrimaryKey = true)]
               public long ID   { get; set; }  //   
          
               [System.Data.Linq.Mapping.Column(Name = "Title", IsPrimaryKey = false)]
               public String Title   { get; set; }  // Book Title  
          
          }
          

          对于java类

          exec [createCode] @TableName='book',@templet =' 
               public @ColumnType @ColumnName ; // @ColumnDesc  
               public @ColumnType get@ColumnName()
               {
                  return this.@ColumnName;
               }
               public void set@ColumnName(@ColumnType @ColumnName)
               {
                  this.@ColumnName=@ColumnName;
               }
          
               '
          

          输出是

          public class  book  
          { 
               public long ID ; //   
               public long getID()
               {
                  return this.ID;
               }
               public void setID(long ID)
               {
                  this.ID=ID;
               }
          
          
               public String Title ; // Book Title  
               public String getTitle()
               {
                  return this.Title;
               }
               public void setTitle(String Title)
               {
                  this.Title=Title;
               } 
          }
          

          适用于安卓 SugarOrm 模型

          exec [createCode] @TableName='book'
          , @befor  ='@Table(name = "@TableName")
          public class @TableName
          {',
             @templet  =' 
               @Column(name = "@ColumnName")
               public @ColumnType @ColumnName ;// @ColumnDesc  
               ' ,
             @after  ='
          }'
          

          输出是

          @Table(name = "book")
          public class book
          { 
               @Column(name = "ID")
               public long ID ;//   
          
               @Column(name = "Title")
               public String Title ;// Book Title  
          
          }
          

          【讨论】:

            【解决方案11】:

            Visual Studio 杂志发表了这篇文章:

            Generating .NET POCO Classes for SQL Query Results

            它有一个可下载的项目,您可以构建它,给它您的 SQL 信息,它会为您制作课程。

            现在,如果该工具刚刚为 SELECT、INSERT 和 UPDATE 创建了 SQL 命令......

            【讨论】:

              【解决方案12】:

              要打印出带有注释(摘要)的 NULLABLE 属性,请使用它。
              这是对第一个答案的轻微修改

              declare @TableName sysname = 'TableName'
              declare @result varchar(max) = 'public class ' + @TableName + '
              {'
              select @result = @result 
              + CASE WHEN ColumnDesc IS NOT NULL THEN '
                  /// <summary>
                  /// ' + ColumnDesc + '
                  /// </summary>' ELSE '' END
              + '
                  public ' + ColumnType + ' ' + ColumnName + ' { get; set; }'
              from
              (
                  select 
                      replace(col.name, ' ', '_') ColumnName,
                      column_id,
                      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 'float'
                          when 'image' then 'byte[]'
                          when 'int' then 'int'
                          when 'money' then 'decimal'
                          when 'nchar' then 'char'
                          when 'ntext' then 'string'
                          when 'numeric' then 'decimal'
                          when 'nvarchar' then 'String'
                          when 'real' then 'double'
                          when 'smalldatetime' then 'DateTime'
                          when 'smallint' then 'short'
                          when 'smallmoney' then 'decimal'
                          when 'text' then 'String'
                          when 'time' then 'TimeSpan'
                          when 'timestamp' then 'DateTime'
                          when 'tinyint' then 'byte'
                          when 'uniqueidentifier' then 'Guid'
                          when 'varbinary' then 'byte[]'
                          when 'varchar' then 'string'
                          else 'UNKNOWN_' + typ.name
                      END + CASE WHEN col.is_nullable=1 AND typ.name NOT IN ('binary', 'varbinary', 'image', 'text', 'ntext', 'varchar', 'nvarchar', 'char', 'nchar') THEN '?' ELSE '' END ColumnType,
                      colDesc.colDesc AS ColumnDesc
                  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
                  OUTER APPLY (
                  SELECT TOP 1 CAST(value AS NVARCHAR(max)) AS colDesc
                  FROM
                     sys.extended_properties
                  WHERE
                     major_id = col.object_id
                     AND
                     minor_id = COLUMNPROPERTY(major_id, col.name, 'ColumnId')
                  ) colDesc            
                  where object_id = object_id(@TableName)
              ) t
              order by column_id
              
              set @result = @result  + '
              }'
              
              print @result
              

              【讨论】:

                【解决方案13】:

                只是想我会为任何感兴趣的人添加我自己的最佳答案变体。 主要特点是:

                • 它将自动为整个架构中的所有表生成类。只需指定架构名称。
                • 它将 System.Data.Linq.Mapping 属性添加到类和每个属性。对使用 Linq to SQL 的任何人都有用。

                  declare @TableName sysname
                  declare @Result varchar(max)
                  declare @schema varchar(20) = 'dbo'
                  DECLARE @Cursor CURSOR
                  
                  SET @Cursor = CURSOR FAST_FORWARD FOR
                  SELECT DISTINCT tablename = rc1.TABLE_NAME
                  FROM INFORMATION_SCHEMA.Tables rc1
                  where rc1.TABLE_SCHEMA = @schema
                  
                  OPEN @Cursor FETCH NEXT FROM @Cursor INTO @TableName
                  
                  WHILE (@@FETCH_STATUS = 0)
                  BEGIN
                  set @Result = '[Table(Name = "' + @schema + '.' + @TableName + '")]
                  public class ' + Replace(@TableName, '$', '_') + '
                  {'
                  
                  select @Result = @Result + '
                      [Column' + PriKey +']
                      public ' + ColumnType + NullableSign + ' ' + ColumnName + ' { get; set; }
                  '
                  from
                  (
                      select 
                          replace(col.name, ' ', '_') ColumnName,
                          col.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,
                          case
                              when pk.CONSTRAINT_NAME is not null and ic.column_id is not null then '(IsPrimaryKey = true, IsDbGenerated = true)'
                              when pk.CONSTRAINT_NAME is not null then '(IsPrimaryKey = true)'
                              when ic.column_id is not null then '(IsDbGenerated = true)'
                              else ''
                          end PriKey
                      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
                      left outer join sys.identity_columns ic on ic.column_id = col.column_id and col.object_id = ic.object_id
                      left outer join (
                          SELECT  K.TABLE_NAME ,
                              K.COLUMN_NAME ,
                              K.CONSTRAINT_NAME
                          FROM    INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C
                                  JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K ON C.TABLE_NAME = K.TABLE_NAME
                                                                                   AND C.CONSTRAINT_CATALOG = K.CONSTRAINT_CATALOG
                                                                                   AND C.CONSTRAINT_SCHEMA = K.CONSTRAINT_SCHEMA
                                                                                   AND C.CONSTRAINT_NAME = K.CONSTRAINT_NAME
                          where C.CONSTRAINT_TYPE = 'PRIMARY KEY'
                      ) pk on pk.COLUMN_NAME = col.name and pk.TABLE_NAME = @TableName
                      where col.object_id = object_id(@schema + '.' + @TableName)
                  ) t
                  order by ColumnId
                  
                  set @Result = @Result  + '
                  }
                  
                  '
                  
                  print @Result
                  
                  FETCH NEXT FROM @Cursor INTO @TableName
                  end
                  
                  CLOSE @Cursor DEALLOCATE @Cursor
                  GO
                  

                【讨论】:

                • 感谢整个架构上的即用型光标,您为我节省了很多时间!
                【解决方案14】:

                商业,但 CodeSmith Generator 可以做到这一点:http://www.codesmithtools.com/product/generator

                【讨论】:

                  【解决方案15】:

                  我对你想要从中得到什么感到困惑,但这里是设计你想要设计的东西时的一般选项。

                  1. 在您的 Visual Studio 版本中使用内置 ORM。
                  2. 自己编写一个,类似于您的代码示例。像往常一样,如果您不确定如何使用,教程是您最好的朋友。
                  3. 使用替代 ORM,例如 NHibernate

                  【讨论】:

                    【解决方案16】:

                    感谢 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
                    ;
                    
                    Thanks Alex and Guilherme!
                    

                    【讨论】:

                    • 谢谢!我只是在找这个!
                    【解决方案17】:

                    Grab QueryFirst,Visual Studio 扩展,可从 SQL 查询生成包装类。你不仅得到...

                    public class MyClass{
                        public string MyProp{get;set;}
                        public int MyNumberProp{get;set;}
                        ...
                    }
                    

                    作为奖励,它会加入......

                    public class MyQuery{
                        public static IEnumerable<MyClass>Execute(){}
                        public static MyClass GetOne(){}
                        ...
                    }
                    

                    您确定要将类直接基于您的表吗?表是属于数据库的静态、规范化数据存储概念。类是动态的、流动的、一次性的、特定于上下文的,也许是非规范化的。为什么不为操作所需的数据编写真正的查询,并让 QueryFirst 从中生成类。

                    【讨论】:

                      【解决方案18】:

                      这篇文章救了我好几次。我只想加两分钱。 对于那些不喜欢使用 ORM 而是编写自己的 DAL 类的人来说,当您在一个表中有 20 列,以及 40 个具有各自 CRUD 操作的不同表时,这既痛苦又浪费时间。我重复了上面的代码,用于根据表实体和属性生成 CRUD 方法。

                       declare @TableName sysname = 'Tablename'
                      declare @Result varchar(max) = 'public class ' + @TableName + '
                      {'
                      
                      select @Result = @Result + '
                          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 'float'
                                  when 'image' then 'byte[]'
                                  when 'int' then 'int'
                                  when 'money' then 'decimal'
                                  when 'nchar' then 'char'
                                  when 'ntext' then 'string'
                                  when 'numeric' then 'decimal'
                                  when 'nvarchar' then 'string'
                                  when 'real' then 'double'
                                  when 'smalldatetime' then 'DateTime'
                                  when 'smallint' then 'short'
                                  when 'smallmoney' then 'decimal'
                                  when 'text' then 'string'
                                  when 'time' then 'TimeSpan'
                                  when 'timestamp' then 'DateTime'
                                  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  + '
                      }'
                      
                      print @Result
                      
                      declare @InitDataAccess varchar(max) = 'public class '+ @TableName +'DataAccess 
                      { '
                      
                      declare @ListStatement varchar(max) ='public List<'+@TableName+'> Get'+@TableName+'List()
                      {
                       String conn = ConfigurationManager.ConnectionStrings["ConnectionNameInWeb.config"].ConnectionString;
                       var itemList = new List<'+@TableName+'>();
                                try
                                  {
                                      using (var sqlCon = new SqlConnection(conn))
                                      {
                                          sqlCon.Open();
                                          var cmd = new SqlCommand
                                          {
                                              Connection = sqlCon,
                                              CommandType = CommandType.StoredProcedure,
                                              CommandText = "StoredProcedureSelectAll"
                                          };
                                          SqlDataReader reader = cmd.ExecuteReader();
                                          while (reader.Read())
                                          {
                                            var item = new '+@TableName+'();
                      ' 
                      select @ListStatement = @ListStatement + '
                      item.'+ ColumnName + '= ('+ ColumnType + NullableSign  +')reader["'+ColumnName+'"];
                      '
                      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 'float'
                                  when 'image' then 'byte[]'
                                  when 'int' then 'int'
                                  when 'money' then 'decimal'
                                  when 'nchar' then 'char'
                                  when 'ntext' then 'string'
                                  when 'numeric' then 'decimal'
                                  when 'nvarchar' then 'string'
                                  when 'real' then 'double'
                                  when 'smalldatetime' then 'DateTime'
                                  when 'smallint' then 'short'
                                  when 'smallmoney' then 'decimal'
                                  when 'text' then 'string'
                                  when 'time' then 'TimeSpan'
                                  when 'timestamp' then 'DateTime'
                                  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
                      
                      select @ListStatement = @ListStatement +'
                                              itemList.Add(item);
                                          }
                      
                                      }
                                  }
                                  catch (Exception ex)
                                  {
                                      throw new Exception(ex.Message);
                                  }
                                  return itemList;
                              }'
                      
                      declare @GetIndividual varchar(max) =  
                      'public '+@TableName+' Get'+@TableName+'()
                      {
                       String conn = ConfigurationManager.ConnectionStrings["ConnectionNameInWeb.config"].ConnectionString;
                       var item = new '+@TableName+'();
                                try
                                  {
                                      using (var sqlCon = new SqlConnection(conn))
                                      {
                                          sqlCon.Open();
                                          var cmd = new SqlCommand
                                          {
                                              Connection = sqlCon,
                                              CommandType = CommandType.StoredProcedure,
                                              CommandText = "StoredProcedureSelectIndividual"
                                          };
                                           cmd.Parameters.AddWithValue("@ItemCriteria", item.id);
                                          SqlDataReader reader = cmd.ExecuteReader();
                                          if (reader.Read())
                                          {' 
                      select @GetIndividual = @GetIndividual + '
                      item.'+ ColumnName + '= ('+ ColumnType + NullableSign  +')reader["'+ColumnName+'"];
                      '
                      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 'float'
                                  when 'image' then 'byte[]'
                                  when 'int' then 'int'
                                  when 'money' then 'decimal'
                                  when 'nchar' then 'char'
                                  when 'ntext' then 'string'
                                  when 'numeric' then 'decimal'
                                  when 'nvarchar' then 'string'
                                  when 'real' then 'double'
                                  when 'smalldatetime' then 'DateTime'
                                  when 'smallint' then 'short'
                                  when 'smallmoney' then 'decimal'
                                  when 'text' then 'string'
                                  when 'time' then 'TimeSpan'
                                  when 'timestamp' then 'DateTime'
                                  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
                      
                      select @GetIndividual = @GetIndividual +'
                      
                                          }
                      
                                      }
                                  }
                                  catch (Exception ex)
                                  {
                                      throw new Exception(ex.Message);
                                  }
                                  return item;
                              }'
                      
                      
                      
                      declare @InsertStatement varchar(max) = 'public void  Insert'+@TableName+'('+@TableName+' item)
                      {
                       String conn = ConfigurationManager.ConnectionStrings["ConnectionNameInWeb.config"].ConnectionString;
                      
                                try
                                  {
                                      using (var sqlCon = new SqlConnection(conn))
                                      {
                                          sqlCon.Open();
                                          var cmd = new SqlCommand
                                          {
                                              Connection = sqlCon,
                                              CommandType = CommandType.StoredProcedure,
                                              CommandText = "StoredProcedureInsert"
                                          };
                      
                                          ' 
                      select @InsertStatement = @InsertStatement + '
                       cmd.Parameters.AddWithValue("@'+ColumnName+'", item.'+ColumnName+');
                      '
                      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 'float'
                                  when 'image' then 'byte[]'
                                  when 'int' then 'int'
                                  when 'money' then 'decimal'
                                  when 'nchar' then 'char'
                                  when 'ntext' then 'string'
                                  when 'numeric' then 'decimal'
                                  when 'nvarchar' then 'string'
                                  when 'real' then 'double'
                                  when 'smalldatetime' then 'DateTime'
                                  when 'smallint' then 'short'
                                  when 'smallmoney' then 'decimal'
                                  when 'text' then 'string'
                                  when 'time' then 'TimeSpan'
                                  when 'timestamp' then 'DateTime'
                                  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
                      
                      select @InsertStatement = @InsertStatement +'
                      
                                          cmd.ExecuteNonQuery();
                      
                                      }
                                  }
                                  catch (Exception ex)
                                  {
                                      throw new Exception(ex.Message);
                                  }
                      
                              }'
                      
                      declare @UpdateStatement varchar(max) = 'public void  Update'+@TableName+'('+@TableName+' item)
                      {
                       String conn = ConfigurationManager.ConnectionStrings["ConnectionNameInWeb.config"].ConnectionString;
                      
                                try
                                  {
                                      using (var sqlCon = new SqlConnection(conn))
                                      {
                                          sqlCon.Open();
                                          var cmd = new SqlCommand
                                          {
                                              Connection = sqlCon,
                                              CommandType = CommandType.StoredProcedure,
                                              CommandText = "StoredProcedureUpdate"
                                          };
                                          cmd.Parameters.AddWithValue("@UpdateCriteria", item.Id);
                                          ' 
                      select @UpdateStatement = @UpdateStatement + '
                       cmd.Parameters.AddWithValue("@'+ColumnName+'", item.'+ColumnName+');
                      '
                      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 'float'
                                  when 'image' then 'byte[]'
                                  when 'int' then 'int'
                                  when 'money' then 'decimal'
                                  when 'nchar' then 'char'
                                  when 'ntext' then 'string'
                                  when 'numeric' then 'decimal'
                                  when 'nvarchar' then 'string'
                                  when 'real' then 'double'
                                  when 'smalldatetime' then 'DateTime'
                                  when 'smallint' then 'short'
                                  when 'smallmoney' then 'decimal'
                                  when 'text' then 'string'
                                  when 'time' then 'TimeSpan'
                                  when 'timestamp' then 'DateTime'
                                  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
                      
                      select @UpdateStatement = @UpdateStatement +'
                      
                                          cmd.ExecuteNonQuery();
                      
                                      }
                                  }
                                  catch (Exception ex)
                                  {
                                      throw new Exception(ex.Message);
                                  }
                      
                              }'
                      
                      declare @EndDataAccess varchar(max)  = '
                      }'
                       print @InitDataAccess
                       print @GetIndividual
                      print @InsertStatement
                      print @UpdateStatement
                      print @ListStatement
                      print @EndDataAccess
                      

                      当然它不是防弹代码,并且可以改进。只是想为这个出色的解决方案做出贡献

                      【讨论】:

                        【解决方案19】:

                        根据上面的回复稍作修改:

                        declare @TableName sysname = 'HistoricCommand'
                        
                        declare @Result varchar(max) = '[System.Data.Linq.Mapping.Table(Name = "' + @TableName + '")]
                        public class Dbo' + @TableName + '
                        {'
                        
                        select @Result = @Result + '
                            [System.Data.Linq.Mapping.Column(Name = "' + t.ColumnName + '", IsPrimaryKey = ' + pkk.ISPK + ')]
                            public ' + ColumnType + NullableSign + ' ' + t.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 'float'
                                    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 'double'
                                    when 'smalldatetime' then 'DateTime'
                                    when 'smallint' then 'short'
                                    when 'smallmoney' then 'decimal'
                                    when 'text' then 'string'
                                    when 'time' then 'TimeSpan'
                                    when 'timestamp' then 'DateTime'
                                    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, 
                        (
                                        SELECT c.name  AS 'ColumnName', CASE WHEN dd.pk IS NULL THEN 'false' ELSE 'true' END ISPK           
                                        FROM        sys.columns c
                                            JOIN    sys.tables  t   ON c.object_id = t.object_id    
                                            LEFT JOIN (SELECT   K.COLUMN_NAME , C.CONSTRAINT_TYPE as pk  
                                                FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K 
                                                    LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C
                                                ON K.TABLE_NAME = C.TABLE_NAME
                                                    AND K.CONSTRAINT_NAME = C.CONSTRAINT_NAME
                                                    AND K.CONSTRAINT_CATALOG = C.CONSTRAINT_CATALOG
                                                    AND K.CONSTRAINT_SCHEMA = C.CONSTRAINT_SCHEMA            
                                                WHERE K.TABLE_NAME = @TableName) as dd
                                             ON dd.COLUMN_NAME = c.name
                                         WHERE       t.name = @TableName            
                                    ) pkk
                        where pkk.ColumnName = t.ColumnName
                        order by ColumnId
                        
                        set @Result = @Result  + '
                        }'
                        
                        print @Result
                        

                        这使得 C# 声明中的完整 LINQ 需要输出

                        [System.Data.Linq.Mapping.Table(Name = "HistoricCommand")]
                        public class DboHistoricCommand
                        {
                            [System.Data.Linq.Mapping.Column(Name = "HistoricCommandId", IsPrimaryKey = true)]
                            public int HistoricCommandId { get; set; }
                        
                            [System.Data.Linq.Mapping.Column(Name = "PHCloudSoftwareInstanceId", IsPrimaryKey = true)]
                            public int PHCloudSoftwareInstanceId { get; set; }
                        
                            [System.Data.Linq.Mapping.Column(Name = "CommandType", IsPrimaryKey = false)]
                            public int CommandType { get; set; }
                        
                            [System.Data.Linq.Mapping.Column(Name = "InitiatedDateTime", IsPrimaryKey = false)]
                            public DateTime InitiatedDateTime { get; set; }
                        
                            [System.Data.Linq.Mapping.Column(Name = "CompletedDateTime", IsPrimaryKey = false)]
                            public DateTime CompletedDateTime { get; set; }
                        
                            [System.Data.Linq.Mapping.Column(Name = "WasSuccessful", IsPrimaryKey = false)]
                            public bool WasSuccessful { get; set; }
                        
                            [System.Data.Linq.Mapping.Column(Name = "Message", IsPrimaryKey = false)]
                            public string Message { get; set; }
                        
                            [System.Data.Linq.Mapping.Column(Name = "ResponseData", IsPrimaryKey = false)]
                            public string ResponseData { get; set; }
                        
                            [System.Data.Linq.Mapping.Column(Name = "Message_orig", IsPrimaryKey = false)]
                            public string Message_orig { get; set; }
                        
                            [System.Data.Linq.Mapping.Column(Name = "Message_XX", IsPrimaryKey = false)]
                            public string Message_XX { get; set; }
                        
                        }
                        

                        【讨论】:

                          【解决方案20】:

                          我在这里将几个基于 SQL 的答案(主要是 Alex Aza 的根答案)中的想法打包到 klassify 中,这是一个控制台应用程序,可以一次为指定数据库生成所有类: p>


                          例如,给定一个表Users,如下所示:

                          +----+------------------+-----------+---------------------+
                          | Id |       Name       | Username  |        Email        |
                          +----+------------------+-----------+---------------------+
                          |  1 | Leanne Graham    | Bret      | Sincere@april.biz   |
                          |  2 | Ervin Howell     | Antonette | Shanna@melissa.tv   |
                          |  3 | Clementine Bauch | Samantha  | Nathan@yesenia.net  |
                          +----+------------------+-----------+---------------------+
                          

                          klassify 将生成一个名为Users.cs 的文件,如下所示:

                              public class User 
                              {
                                  public int Id {get; set; }
                                  public string Name { get;set; }
                                  public string Username { get; set; }
                                  public string Email { get; set; }
                              }
                          

                          它将为每个表输出一个文件。丢弃你不使用的东西。

                          用法

                           --out, -o:
                                  output directory     << defaults to the current directory >>
                           --user, -u:
                                  sql server user id   << required >>
                           --password, -p:
                                  sql server password  << required >>
                           --server, -s:
                                  sql server           << defaults to localhost >>
                           --database, -d:
                                  sql database         << required >>
                           --timeout, -t:
                                  connection timeout   << defaults to 30 >>
                           --help, -h:
                                  show help
                          

                          【讨论】:

                            【解决方案21】:

                            Oracle DB 的另一种解决方案 -> C#

                            • 单一查询
                            • 无函数无过程
                            • 多表

                            添加数据注释

                            • [键]
                            • [必填]
                            • [表格]
                            • [字符串长度]
                            • [列]
                            • 可以为空

                            查询

                            https://gist.github.com/omansak/f19eefffd2d639ac72a1f4b506d8471a

                            输出

                            [Table("AGENTS")]
                            public class Agents
                            {
                                [Key]
                                [Required]
                                [Column("INT_ID", TypeName = "NUMBER(10,0)", Order = 1)]
                                public long IntId { get; set; }
                                [Key]
                                [Required]
                                [StringLength(15)]
                                [Column("REFERENCE_CODE", TypeName = "VARCHAR2(15)", Order = 2)]
                                public string ReferenceCode { get; set; }
                                [Required]
                                [Column("PARENT_INT_ID", TypeName = "NUMBER(10,0)", Order = 3)]
                                public long ParentIntId { get; set; }
                                [Required]
                                [StringLength(200)]
                                [Column("TITLE", TypeName = "VARCHAR2(200)", Order = 4)]
                                public string Title { get; set; }
                                [Required]
                                [Column("START_DATE", TypeName = "DATE", Order = 5)]
                                public DateTime StartDate { get; set; }
                                [Required]
                                [Column("END_DATE", TypeName = "DATE", Order = 6)]
                                public DateTime EndDate { get; set; }
                                [Required]
                                [StringLength(1)]
                                [Column("AGENT_TYPE", TypeName = "VARCHAR2(1)", Order = 7)]
                                public string AgentType { get; set; }
                                [Required]
                                [Column("CREATE_DATE", TypeName = "DATE", Order = 8)]
                                public DateTime CreateDate { get; set; }
                                [Required]
                                [StringLength(32)]
                                [Column("CREATE_USER", TypeName = "VARCHAR2(32)", Order = 9)]
                                public string CreateUser { get; set; }
                                [StringLength(200)]
                                [Column("RESPONSIBLE_CONTACT", TypeName = "VARCHAR2(200)", Order = 10)]
                                public string ResponsibleContact { get; set; }
                                [StringLength(100)]
                                [Column("RESPONSIBLE_TITLE", TypeName = "VARCHAR2(100)", Order = 11)]
                                public string ResponsibleTitle { get; set; }
                                [StringLength(100)]
                                [Column("AGENCY_PLATE_NO", TypeName = "VARCHAR2(100)", Order = 12)]
                                public string AgencyPlateNo { get; set; }
                                [Column("AGENCY_COVER_AMOUNT", TypeName = "NUMBER(24,2)", Order = 13)]
                                public double? AgencyCoverAmount { get; set; }
                                [StringLength(100)]
                                [Column("MERSIS_NO", TypeName = "VARCHAR2(100)", Order = 14)]
                                public string MersisNo { get; set; }
                                [StringLength(100)]
                                [Column("TECH_PERSONEL_NO", TypeName = "VARCHAR2(100)", Order = 15)]
                                public string TechPersonelNo { get; set; }
                                [StringLength(100)]
                                [Column("TECH_PERSONEL_NAME", TypeName = "VARCHAR2(100)", Order = 16)]
                                public string TechPersonelName { get; set; }
                                [Column("COVER_END_DATE", TypeName = "DATE", Order = 17)]
                                public DateTime? CoverEndDate { get; set; }
                                [Column("BRANCH_NUMBER", TypeName = "NUMBER(10,0)", Order = 18)]
                                public long? BranchNumber { get; set; }
                                [Column("ACTION_NUMBER", TypeName = "NUMBER(10,0)", Order = 19)]
                                public long? ActionNumber { get; set; }
                                [Column("CLUB_PARTICIPATION_COUNT", TypeName = "NUMBER(10,0)", Order = 20)]
                                public long? ClubParticipationCount { get; set; }
                                [Column("AGENCY_CONTRACT_DATE", TypeName = "DATE", Order = 21)]
                                public DateTime? AgencyContractDate { get; set; }
                                [StringLength(200)]
                                [Column("KEP_ADDRESS", TypeName = "VARCHAR2(200)", Order = 22)]
                                public string KepAddress { get; set; }
                            }
                            

                            【讨论】:

                            • PS : 如果您的表有多个主键,您必须使用 fluent API 设置 PK
                            【解决方案22】:

                            最简单的方法是EF,逆向工程师。 http://msdn.microsoft.com/en-US/data/jj593170

                            【讨论】:

                              【解决方案23】:

                              我喜欢使用私有本地成员和公共访问器/修改器来设置我的课程。 所以我修改了上面 Alex 的脚本,让感兴趣的人也能做到这一点。

                              declare @TableName sysname = 'TABLE_NAME'
                              declare @result varchar(max) = 'public class ' + @TableName + '
                              {'
                              
                              SET @result = @result + 
                              '
                                  public ' + @TableName + '()
                                  {}
                              ';
                              
                              select @result = @result + '
                                  private ' + ColumnType + ' ' + ' m_' + stuff(replace(ColumnName, '_', ''), 1, 1, lower(left(ColumnName, 1))) + ';'
                              from
                              (
                                  select 
                                      replace(col.name, ' ', '_') ColumnName,
                                      column_id,
                                      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 'float'
                                          when 'image' then 'byte[]'
                                          when 'int' then 'int'
                                          when 'money' then 'decimal'
                                          when 'nchar' then 'char'
                                          when 'ntext' then 'string'
                                          when 'numeric' then 'decimal'
                                          when 'nvarchar' then 'string'
                                          when 'real' then 'double'
                                          when 'smalldatetime' then 'DateTime'
                                          when 'smallint' then 'short'
                                          when 'smallmoney' then 'decimal'
                                          when 'text' then 'string'
                                          when 'time' then 'TimeSpan'
                                          when 'timestamp' then 'DateTime'
                                          when 'tinyint' then 'byte'
                                          when 'uniqueidentifier' then 'Guid'
                                          when 'varbinary' then 'byte[]'
                                          when 'varchar' then 'string'
                                          else 'UNKNOWN_' + typ.name
                                      end ColumnType
                                  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 column_id
                              
                              SET @result = @result + '
                              '
                              
                              select @result = @result + '
                                  public ' + ColumnType + ' ' + ColumnName + ' { get { return m_' + stuff(replace(ColumnName, '_', ''), 1, 1, lower(left(ColumnName, 1))) + ';} set {m_' + stuff(replace(ColumnName, '_', ''), 1, 1, lower(left(ColumnName, 1))) + ' = value;} }' from
                              (
                                  select 
                                      replace(col.name, ' ', '_') ColumnName,
                                      column_id,
                                      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 'float'
                                          when 'image' then 'byte[]'
                                          when 'int' then 'int'
                                          when 'money' then 'decimal'
                                          when 'nchar' then 'char'
                                          when 'ntext' then 'string'
                                          when 'numeric' then 'decimal'
                                          when 'nvarchar' then 'string'
                                          when 'real' then 'double'
                                          when 'smalldatetime' then 'DateTime'
                                          when 'smallint' then 'short'
                                          when 'smallmoney' then 'decimal'
                                          when 'text' then 'string'
                                          when 'time' then 'TimeSpan'
                                          when 'timestamp' then 'DateTime'
                                          when 'tinyint' then 'byte'
                                          when 'uniqueidentifier' then 'Guid'
                                          when 'varbinary' then 'byte[]'
                                          when 'varchar' then 'string'
                                          else 'UNKNOWN_' + typ.name
                                      end ColumnType
                                  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 column_id
                              
                              set @result = @result  + '
                              }'
                              
                              print @result
                              

                              【讨论】:

                                【解决方案24】:

                                对之前解决方案的一个小补充: object_id(@TableName) 仅在您使用默认架构时才有效。

                                (Select id from sysobjects where name = @TableName)
                                

                                只要@tableName 是唯一的,就可以在任何架构中工作。

                                【讨论】:

                                  【解决方案25】:

                                  如果它对其他任何人有用,使用属性映射的 Code-First 方法,我想要一些只需要在对象模型中绑定实体的东西。所以感谢 Carnotaurus 的回答,我根据他们自己的建议对其进行了扩展并进行了一些调整。

                                  因此,这依赖于包含两个部分的解决方案,这两个部分都是 SQL 标量值函数:

                                  1. “初始大写”函数(取自: https://social.msdn.microsoft.com/Forums/sqlserver/en-US/8a58dbe1-7a4b-4287-afdc-bfecb4e69b23/similar-to-initcap-in-sql-server-tsql 并稍作修改以满足我的需要)
                                  ALTER function [dbo].[ProperCase] (@cStringToProper varchar(8000))
                                  returns varchar(8000)
                                  as
                                  begin
                                     declare  @Position int
                                      select @cStringToProper = stuff(lower(@cStringToProper) , 1 , 1 , upper(left(@cStringToProper , 1)))
                                          , @Position = patindex('%[^a-zA-Z][a-z]%' , @cStringToProper collate Latin1_General_Bin)
                                  
                                     while @Position > 0
                                           select @cStringToProper = stuff(@cStringToProper , @Position , 2 , upper(substring(@cStringToProper , @Position , 2)))
                                                , @Position = patindex('%[^a-zA-Z][a-z]%' , @cStringToProper collate Latin1_General_Bin)
                                  
                                    select @cStringToProper = replace(@cStringToProper, '_','')
                                  
                                     return @cStringToProper
                                  end
                                  
                                  1. 输出函数本身,它通过以下方式扩展 Carnotaurus 的解决方案:

                                    • 正确输出换行符
                                    • 执行一些基本的制表
                                    • 写出适当的 [Table] 映射(按照建议)
                                    • 写出适当的 [Column] 映射,包括类型名称(按照建议)
                                    • 允许实体名称与表名不同
                                    • 修复了当您拥有包含大量列的表时 Print @Result 截断的限制
                                  CREATE FUNCTION [dbo].[GetEntityObject] (@NameSpace NVARCHAR(MAX), @TableName NVARCHAR(MAX), @EntityName NVARCHAR(MAX))  RETURNS NVARCHAR(MAX) AS BEGIN
                                  
                                  DECLARE @result NVARCHAR(MAX)
                                  
                                  SET @result = @result + 'using System;' + CHAR(13) + CHAR(13) 
                                  
                                  IF (@NameSpace IS NOT NULL)  BEGIN
                                      SET @result = @result + 'namespace ' + @NameSpace  + CHAR(13) + '{' + CHAR(13)  END
                                  
                                  SET @result = @result + '[Table(name: ' + CHAR(34) + @TableName + CHAR(34) + ')]' + CHAR(13) SET @result = @result + 'public class ' + @EntityName + CHAR(13) + '{' + CHAR(13) 
                                  
                                  SET @result = @result + '#region Instance Properties' + CHAR(13)  
                                  
                                  SELECT @result = @result + CHAR(13)     + '[Column(name: ' + CHAR(34) + OriginalColumnName + CHAR(34) + ', TypeName = ' + CHAR(34) + DataType
                                  + CHAR(34) + ')]' + CHAR(13)
                                      + 'public ' + ColumnType + ' ' + ColumnName + ' { get; set; } ' + CHAR(13)  FROM (
                                      SELECT dbo.ProperCase (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 'Boolean?' ELSE 'Boolean' 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 'Int32?' ELSE 'Int32' 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 
                                                  CASE C.IS_NULLABLE
                                                      WHEN 'YES' THEN 'DateTime?' ELSE 'DateTime' END                                    
                                              WHEN 'tinyint' THEN 
                                                  CASE C.IS_NULLABLE
                                                      WHEN 'YES' THEN 'Byte?' ELSE 'Byte' END                                                
                                              WHEN 'uniqueidentifier' THEN 'Guid'
                                              WHEN 'varbinary' THEN 'Byte[]'
                                              WHEN 'varchar' THEN 'String'
                                              ELSE 'Object'
                                          END AS ColumnType
                                          , c.ORDINAL_POSITION        , c.COLUMN_NAME as OriginalColumnName       ,c.DATA_TYPE as DataType
                                  
                                  FROM    INFORMATION_SCHEMA.COLUMNS c WHERE   c.TABLE_NAME = @TableName) t ORDER BY t.ORDINAL_POSITION
                                  
                                  SET @result = @result + CHAR(13) + '#endregion Instance Properties' + CHAR(13)  
                                  
                                  SET @result = @result  + '}' + CHAR(13)
                                  
                                  IF (@TableName IS NOT NULL)  BEGIN
                                      SET @result = @result + CHAR(13) + '}'  END
                                  
                                  return @result END
                                  

                                  在 MS SQL Management Studio 中使用:

                                  SELECT dbo.GetEntityObject('MyNameSpace', 'MyTableName', 'MyEntityName')

                                  将生成一个列值,您可以将其复制并粘贴到 Visual Studio 中。

                                  如果它对任何人都有帮助,那就太好了!

                                  【讨论】:

                                  • 我没有添加 [Key] 属性,因为手动添加它很容易。此外,您可能会遇到错误,即无法将 Real 映射到 Edm.Double[Nullable=True,DefaultValue=]。如果是这种情况,请尝试修改相关属性或将 Real 映射到 Single 的函数。
                                  【解决方案26】:

                                  Java 类生成

                                  declare @TableName varchar(max) = 'Restaurants'
                                  declare @Templete varchar(max) = ' 
                                       public @ColumnType @ColumnName ; // @ColumnDesc  
                                       public @ColumnType get@ColumnName()
                                       {
                                          return this.@ColumnName;
                                       }
                                       public void set@ColumnName(@ColumnType @ColumnName)
                                       {
                                          this.@ColumnName=@ColumnName;
                                       }
                                  
                                       '
                                  declare @before varchar(max)='public class  @TableName  
                                  {'
                                     
                                  declare @after varchar(max)='
                                  }'
                                  
                                  
                                  
                                  declare @result varchar(max)
                                  
                                  set @before =replace(@before,'@TableName',@TableName)
                                  
                                  set @result=@before
                                  
                                  select @result = @result 
                                  + replace(replace(replace(replace(replace(@Templete,'@ColumnType',ColumnType) ,'@ColumnName',ColumnName) ,'@ColumnDesc',ColumnDesc),'@ISPK',ISPK),'@max_length',max_length)
                                  
                                  from  
                                  (
                                      select 
                                      column_id,
                                      replace(col.name, ' ', '_') ColumnName,
                                      typ.name as sqltype,
                                      typ.max_length,
                                      is_identity,
                                      pkk.ISPK, 
                                          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 'float'
                                              when 'image' then 'byte[]'
                                              when 'int' then 'int'
                                              when 'money' then 'decimal'
                                              when 'nchar' then 'char'
                                              when 'ntext' then 'string'
                                              when 'numeric' then 'decimal'
                                              when 'nvarchar' then 'String'
                                              when 'real' then 'double'
                                              when 'smalldatetime' then 'DateTime'
                                              when 'smallint' then 'short'
                                              when 'smallmoney' then 'decimal'
                                              when 'text' then 'String'
                                              when 'time' then 'TimeSpan'
                                              when 'timestamp' then 'DateTime'
                                              when 'tinyint' then 'byte'
                                              when 'uniqueidentifier' then 'Guid'
                                              when 'varbinary' then 'byte[]'
                                              when 'varchar' then 'string'
                                              else 'UNKNOWN_' + typ.name
                                          END + CASE WHEN col.is_nullable=1 AND typ.name NOT IN ('binary', 'varbinary', 'image', 'text', 'ntext', 'varchar', 'nvarchar', 'char', 'nchar') THEN '?' ELSE '' END ColumnType,
                                        isnull(colDesc.colDesc,'') AS ColumnDesc 
                                      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
                                              left join
                                              (
                                                  SELECT c.name  AS 'ColumnName', CASE WHEN dd.pk IS NULL THEN 'false' ELSE 'true' END ISPK           
                                                  FROM        sys.columns c
                                                      JOIN    sys.tables  t   ON c.object_id = t.object_id    
                                                      LEFT JOIN (SELECT   K.COLUMN_NAME , C.CONSTRAINT_TYPE as pk  
                                                          FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K 
                                                              LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C
                                                          ON K.TABLE_NAME = C.TABLE_NAME
                                                              AND K.CONSTRAINT_NAME = C.CONSTRAINT_NAME
                                                              AND K.CONSTRAINT_CATALOG = C.CONSTRAINT_CATALOG
                                                              AND K.CONSTRAINT_SCHEMA = C.CONSTRAINT_SCHEMA            
                                                          WHERE K.TABLE_NAME = @TableName) as dd
                                                       ON dd.COLUMN_NAME = c.name
                                                   WHERE       t.name = @TableName       
                                              ) pkk  on ColumnName=col.name
                                  
                                      OUTER APPLY (
                                      SELECT TOP 1 CAST(value AS NVARCHAR(max)) AS colDesc
                                      FROM
                                         sys.extended_properties
                                      WHERE
                                         major_id = col.object_id
                                         AND
                                         minor_id = COLUMNPROPERTY(major_id, col.name, 'ColumnId')
                                      ) colDesc      
                                      where object_id = object_id(@TableName)
                                  
                                      ) t
                                  
                                      set @result=@result+@after
                                  
                                      select @result
                                      --print @result
                                  

                                  【讨论】:

                                    【解决方案27】:

                                    由于之前没有人提到过,所以还有 Scaffold-DbContext

                                    在 NuGet 包管理器控制台中键入以下内容: Scaffold-DbContext "Your Connection String" Microsoft.EntityFrameworkCore.SqlServer -OutputDir "Output Directory"

                                    【讨论】:

                                      【解决方案28】:

                                      从 Postgres 数据库生成

                                      DO $$ DECLARE v_tabela varchar; DECLARE v_cursor_colunas record; DECLARE v_nome_coluna varchar; DECLARE v_classe VARCHAR; DECLARE v_tipo VARCHAR; DECLARE v_schema_name VARCHAR; BEGIN v_schema_name := 'my-schema'; v_tabela := 'my-table'; select table_name INTO v_tabela from information_schema.tables where table_schema = v_schema_name and table_type = 'BASE TABLE' and table_name = v_tabela; v_classe := E'\r\n' || 'public class ' || v_tabela || ' {' || E'\r\n'; FOR v_cursor_colunas IN SELECT column_name as coluna, is_nullable as isnull, data_type as tipo, character_maximum_length as tamanho FROM information_schema.columns WHERE table_schema = v_schema_name AND table_name = v_tabela LOOP
                                      IF v_cursor_colunas.tipo='character varying' THEN v_tipo:= 'string'; ELSIF v_cursor_colunas.tipo='character' and v_cursor_colunas.tamanho=1 THEN v_tipo:= 'char'; ELSIF v_cursor_colunas.tipo='character' and v_cursor_colunas.tamanho<>1 THEN v_tipo:= 'string'; ELSIF v_cursor_colunas.tipo like 'timestamp%' THEN v_tipo:= 'DateTime'; IF v_cursor_colunas.isnull='YES' then v_tipo:= 'DateTime?'; END IF; ELSIF v_cursor_colunas.tipo='boolean' THEN v_tipo:= 'bool'; IF v_cursor_colunas.isnull='YES' then v_tipo:= 'bool?'; END IF; ELSIF v_cursor_colunas.tipo='integer' THEN v_tipo:= 'int'; IF v_cursor_colunas.isnull='YES' then v_tipo:= 'int?'; END IF; ELSIF v_cursor_colunas.tipo='numeric' THEN v_tipo:= 'double'; IF v_cursor_colunas.isnull='YES' then v_tipo:= 'double?'; END IF; ELSIF v_cursor_colunas.tipo='text' THEN v_tipo:= 'string'; ELSE v_tipo:= 'another'; END IF;
                                      v_nome_coluna := v_cursor_colunas.coluna; v_classe := v_classe || 'public ' || v_tipo || ' ' || v_cursor_colunas.coluna || ' { get; set; }' || E'\r\n';
                                      END LOOP;

                                      v_classe := v_classe || E'\r\n' || '}';
                                      提高通知 '%' , v_classe; 结束$$;

                                      【讨论】:

                                        【解决方案29】:

                                        Postgres DB 的另一种解决方案 -> C#

                                            SELECT
                                                    CASE 
                                                        WHEN c.is_nullable ='NO'  THEN '[Required]'||chr(10)
                                                        ELSE '' END
                                                    ||CASE 
                                                        WHEN c.data_type = 'character varying' THEN format('[StringLength(%s)]',c.character_maximum_length)||chr(10)
                                                        ELSE '' END
                                                    ||'public '
                                                    ||CASE 
                                                        WHEN c.data_type = 'integer' THEN 'int'
                                                        WHEN c.data_type = 'boolean' THEN 'bool'
                                                        WHEN c.data_type = 'double precision' THEN 'double'
                                                        WHEN c.data_type = 'uuid' THEN 'Guid'
                                                        WHEN c.data_type = 'character varying' THEN 'string'
                                                        WHEN c.data_type = 'timestamp without time zone' THEN 'DateTime'    
                                                        WHEN c.data_type = 'bigint' THEN 'long'   
                                                        WHEN c.data_type = 'bytea' THEN 'byte[]'    
                                                    ELSE 'object' END
                                                    ||CASE
                                                        WHEN c.is_nullable='YES' AND NOT  c.data_type = 'character varying' THEN '? '
                                                        ELSE ' ' END
                                                    ||c.column_name||' {get;set;}'
                                                    ,c.*
                                            FROM information_schema."columns" c
                                            WHERE 1=1
                                            AND c.table_name='YOUR_TABLE_NAME'
                                        
                                        
                                        

                                        【讨论】:

                                          【解决方案30】:

                                          只要您的表格包含两列并且被称为“tblPeople”之类的名称,您就可以做到。

                                          您始终可以编写自己的 SQL 包装器。我实际上更喜欢这样做,我讨厌以任何方式生成的代码。

                                          也许创建一个DAL 类,并有一个名为GetPerson(int id) 的方法,用于查询该人的数据库,然后从结果集中创建您的Person 对象。

                                          【讨论】:

                                            猜你喜欢
                                            • 2011-03-18
                                            • 2010-09-08
                                            • 2010-10-23
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 2016-06-18
                                            相关资源
                                            最近更新 更多