RKh*_*RKh 13 visual-studio-2010 dapper micro-orm
我来自PetaPoco营地.PetaPoco有一个T4模板,可以从数据库中生成模型.Dapper有类似的东西吗?
我使用NuGet安装了Dapper并添加了SqlHelper.cs,但是我没有找到任何从数据库生成模型的东西.
Mat*_*hie 43
我刚刚写了一个SQL查询来为自己完成这项工作.并在需要时使用额外类型更新它.只需将表名称替换为@@@@.
为了制作很多表,我创建了一个临时存储过程来调用.例如.
exec createTablePOCO(@tableName)
SELECT
'public ' + a1.NewType + ' ' + a1.COLUMN_NAME + ' {get;set;}'
,*
FROM
(
/*using top because i'm putting an order by ordinal_position on it.
putting a top on it is the only way for a subquery to be ordered*/
SELECT TOP 100 PERCENT
COLUMN_NAME,
DATA_TYPE,
IS_NULLABLE,
CASE
WHEN DATA_TYPE = 'varchar' THEN 'string'
WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'NO' THEN 'DateTime'
WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'YES' THEN 'DateTime?'
WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'YES' THEN 'int?'
WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'NO' THEN 'int'
WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'NO' THEN 'Int16'
WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'YES' THEN 'Int16?'
WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'NO' THEN 'decimal'
WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'YES' THEN 'decimal?'
WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'NO' THEN 'decimal'
WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'YES' THEN 'decimal?'
WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'NO' THEN 'decimal'
WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'YES' THEN 'decimal?'
WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'NO' THEN 'long'
WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'YES' THEN 'long?'
WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'NO' THEN 'byte'
WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'YES' THEN 'byte?'
WHEN DATA_TYPE = 'char' THEN 'string'
WHEN DATA_TYPE = 'timestamp' THEN 'byte[]'
WHEN DATA_TYPE = 'varbinary' THEN 'byte[]'
WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'NO' THEN 'bool'
WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'YES' THEN 'bool?'
WHEN DATA_TYPE = 'xml' THEN 'string'
END AS NewType
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '@@@@'
ORDER BY ORDINAL_POSITION
) AS a1
Run Code Online (Sandbox Code Playgroud)
Dapper 本身为连接对象提供了很少的扩展方法(查询、执行),并且没有“模型生成器”。也许可以使用其他一些框架来基于数据库模式生成 POCO。
更新:
Run Code Online (Sandbox Code Playgroud)<#@ template language="C#" debug="True" #> <#@ assembly name="System" #> <#@ assembly name="System.Data" #> <#@ assembly name="System.Core" #> <#@ assembly name="System.Xml" #> <#@ assembly name="Microsoft.SqlServer.ConnectionInfo" #> <#@ assembly name="Microsoft.SqlServer.Management.Sdk.Sfc" #> <#@ assembly name="Microsoft.SqlServer.Smo" #> <#@ import namespace="System" #> <#@ import namespace="System.Text" #> <#@ import namespace="System.Xml" #> <#@ import namespace="Microsoft.SqlServer.Management.Smo" #> <#@ import namespace="System.Data.SqlClient" #> <#@ import namespace="Microsoft.SqlServer.Management.Common" #> namespace Namespace { <# var databaseName = "testDb"; var serverConnection = new SqlConnection( @"Data Source=.\SQLEXPRESS; Integrated Security=true; Initial Catalog=" + databaseName); var svrConnection = new ServerConnection(serverConnection); Server srv = new Server(svrConnection); foreach (Table table in srv.Databases[databaseName].Tables) { #> class <#= table.Name #> { <# foreach (Column col in table.Columns) { #> public <#= GetNetDataType(col.DataType.Name) #> <#= col.Name #> { get; set; } <# } #> } <# } #> } <#+ public static string GetNetDataType(string sqlDataTypeName) { switch (sqlDataTypeName.ToLower()) { case "bigint": return "Int64"; case "binary": return "Byte[]"; case "bit": return "bool"; case "char": return "char"; case "cursor": return string.Empty; case "datetime": return "DateTime"; case "decimal": return "Decimal"; case "float": return "Double"; case "int": return "int"; case "money": return "Decimal"; case "nchar": return "string"; case "numeric": return "Decimal"; case "nvarchar": return "string"; case "real": return "single"; case "smallint": return "Int16"; case "text": return "string"; case "tinyint": return "Byte"; case "varbinary": return "Byte[]"; case "xml": return "string"; case "varchar": return "string"; case "smalldatetime": return "DateTime"; case "image": return "byte[]"; default: return string.Empty; } } #>
如果你结合提到的sp mattritchies(参见上面的答案)并从游标调用它,你可以为数据库中的每个表生成poco类
USE YourDataBaseName
GO
DECLARE @field1 nvarchar(400)
DECLARE cur CURSOR LOCAL for
SELECT TABLE_NAME FROM information_schema.tables
OPEN cur
FETCH NEXT FROM cur INTO @field1 --, @field2
WHILE @@FETCH_STATUS = 0 BEGIN
exec Helper_CreatePocoFromTableName @field1 -- , @field2
fetch next from cur into @field1 -- , @field2
END
close cur
deallocate cur
Run Code Online (Sandbox Code Playgroud)
我从mattritchies回答(见上文)中获取了sql并创建了他提到的存储过程并对其进行了一些修改,以便它也添加了类名.如果将Management Studio置于文本输出模式并删除列名称的输出,则会获得所有类的复制粘贴文本:
CREATE PROCEDURE [dbo].[Helper_CreatePocoFromTableName]
@tableName varchar(100)
AS
BEGIN
SET NOCOUNT ON;
-- Subquery to return only the copy paste text
Select PropertyColumn from (
SELECT 1 as rowNr, 'public class ' + @tableName + ' {' as PropertyColumn
UNION
SELECT 2 as rowNr, 'public ' + a1.NewType + ' ' + a1.COLUMN_NAME + ' {get;set;}' as PropertyColumn
-- ,* comment added so that i get copy pasteable output
FROM
(
/*using top because i'm putting an order by ordinal_position on it.
putting a top on it is the only way for a subquery to be ordered*/
SELECT TOP 100 PERCENT
COLUMN_NAME,
DATA_TYPE,
IS_NULLABLE,
CASE
WHEN DATA_TYPE = 'varchar' THEN 'string'
WHEN DATA_TYPE = 'nvarchar' THEN 'string'
WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'NO' THEN 'DateTime'
WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'YES' THEN 'DateTime?'
WHEN DATA_TYPE = 'smalldatetime' AND IS_NULLABLE = 'NO' THEN 'DateTime'
WHEN DATA_TYPE = 'datetime2' AND IS_NULLABLE = 'NO' THEN 'DateTime'
WHEN DATA_TYPE = 'smalldatetime' AND IS_NULLABLE = 'YES' THEN 'DateTime?'
WHEN DATA_TYPE = 'datetime2' AND IS_NULLABLE = 'YES' THEN 'DateTime?'
WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'YES' THEN 'int?'
WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'NO' THEN 'int'
WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'NO' THEN 'Int16'
WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'YES' THEN 'Int16?'
WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'NO' THEN 'decimal'
WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'YES' THEN 'decimal?'
WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'NO' THEN 'decimal'
WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'YES' THEN 'decimal?'
WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'NO' THEN 'decimal'
WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'YES' THEN 'decimal?'
WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'NO' THEN 'long'
WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'YES' THEN 'long?'
WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'NO' THEN 'byte'
WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'YES' THEN 'byte?'
WHEN DATA_TYPE = 'char' THEN 'string'
WHEN DATA_TYPE = 'timestamp' THEN 'byte[]'
WHEN DATA_TYPE = 'varbinary' THEN 'byte[]'
WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'NO' THEN 'bool'
WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'YES' THEN 'bool?'
WHEN DATA_TYPE = 'xml' THEN 'string'
END AS NewType
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @tableName
ORDER BY ORDINAL_POSITION
) AS a1
UNION
SELECT 3 as rowNr, '} // class ' + @tableName
) as t Order By rowNr asc
END
Run Code Online (Sandbox Code Playgroud)
PS:我会把它作为他的答案的编辑建议,但我的经验是,经常编辑建议被拒绝.
用户chris-w-mclean建议我自己没有尝试过以下更改(请参阅他的建议编辑):
SELECT 1 as rowNr, 'public class '为SELECT 1.0 as rowNr, 'public class ' SELECT 2 as rowNr, 'public '为SELECT 2 + a1.ORDINAL_POSITION/1000 as rowNr, 'public ' SELECT TOP 100 PERCENT COLUMN_NAME,为SELECT COLUMN_NAME, IS_NULLABLE, CASE这一行之间添加cast(ORDINAL_POSITION as float) as ORDINAL_POSITION,ORDER BY ORDINAL_POSITIONSELECT 3 as以SELECT 3.0 as 尝试我稍微优化过的这个版本,这样结果就不需要通过管道传输到文本输出。相反,PRINT 语句允许轻松复制/粘贴输出。我还删除了子查询并添加了 nvarchar/ntext 类型的声明。
这是针对单个表的,但可以将其转换为存储过程以使用上面的游标建议之一。
SET NOCOUNT ON
DECLARE @tbl as varchar(255)
SET @tbl = '@@@@'
DECLARE @flds as varchar(8000)
SET @flds=''
SELECT -1 as f0, 'public class ' + @tbl + ' {' as f1 into #tmp
INSERT #tmp
SELECT
ORDINAL_POSITION,
' public ' +
CASE
WHEN DATA_TYPE = 'varchar' THEN 'string'
WHEN DATA_TYPE = 'nvarchar' THEN 'string'
WHEN DATA_TYPE = 'text' THEN 'string'
WHEN DATA_TYPE = 'ntext' THEN 'string'
WHEN DATA_TYPE = 'char' THEN 'string'
WHEN DATA_TYPE = 'xml' THEN 'string'
WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'NO' THEN 'DateTime'
WHEN DATA_TYPE = 'datetime' AND IS_NULLABLE = 'YES' THEN 'DateTime?'
WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'YES' THEN 'int?'
WHEN DATA_TYPE = 'int' AND IS_NULLABLE = 'NO' THEN 'int'
WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'NO' THEN 'Int16'
WHEN DATA_TYPE = 'smallint' AND IS_NULLABLE = 'YES' THEN 'Int16?'
WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'NO' THEN 'decimal'
WHEN DATA_TYPE = 'decimal' AND IS_NULLABLE = 'YES' THEN 'decimal?'
WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'NO' THEN 'decimal'
WHEN DATA_TYPE = 'numeric' AND IS_NULLABLE = 'YES' THEN 'decimal?'
WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'NO' THEN 'decimal'
WHEN DATA_TYPE = 'money' AND IS_NULLABLE = 'YES' THEN 'decimal?'
WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'NO' THEN 'long'
WHEN DATA_TYPE = 'bigint' AND IS_NULLABLE = 'YES' THEN 'long?'
WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'NO' THEN 'byte'
WHEN DATA_TYPE = 'tinyint' AND IS_NULLABLE = 'YES' THEN 'byte?'
WHEN DATA_TYPE = 'timestamp' THEN 'byte[]'
WHEN DATA_TYPE = 'varbinary' THEN 'byte[]'
WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'NO' THEN 'bool'
WHEN DATA_TYPE = 'bit' AND IS_NULLABLE = 'YES' THEN 'bool?'
END + ' ' + COLUMN_NAME + ' {get;set;}'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = @tbl
INSERT #tmp SELECT 999, '}'
SELECT @flds=@flds + f1 +'
' from #tmp order by f0
DROP TABLE #tmp
PRINT @flds
Run Code Online (Sandbox Code Playgroud)
我的方法是:
<dynamic>获取一些没有类型的行IE:
var persons = connection.Query<dynamic>("SELECT * FROM Persons");
var serializedPerson = JsonConvert.Serialize(persons.First());
Console.WriteLine(serializedPerson);
Run Code Online (Sandbox Code Playgroud)