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



当前回答

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

其他回答

设置@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

Postgres DB -> c#的另一个解决方案

兼容NpgSQL 添加DataAnnotations

    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'


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

sql2object.com

这可以让你安全地输入所有的属性和类型。

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

之前的解决方案的一个小补充: object_id(@TableName)仅在默认模式中有效。

(Select id from sysobjects where name = @TableName)

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

抓取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(){}
    ...
}

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