C# Dapper的SQL查询生成器
Hi试图在我们的新项目中找到性能最好的ORM。我最后的选择变得得体了。我们还需要让我们的应用程序包括(至少)以下特性,这些特性防止我们硬编码SQL查询以传递给DapperC# Dapper的SQL查询生成器,c#,sql,orm,dapper,C#,Sql,Orm,Dapper,Hi试图在我们的新项目中找到性能最好的ORM。我最后的选择变得得体了。我们还需要让我们的应用程序包括(至少)以下特性,这些特性防止我们硬编码SQL查询以传递给Dapper 独立于数据库 运行时实体定义 我曾考虑为Dapper编写一个SQL生成器,但我不确定我采用的方法是否是最好的: 声明具有签名方法的接口。该实现对应于要使用的数据库系统(SQL Server/MySQL/PostgreSql/DB2/Oracle/etc…) 使用以下格式创建数据库XML架构: <sqltable name
<sqltable name="Foo">
<sqlfield name="ID" primarykey="1" />
<sqlfield name="Name" />
<sqlfield name="Surname />
<sqlfield name="etc" />
<sqlreference name"KooID" table="Koo" field="ID" />
</sqltable>
SELECT
INSERT INTO
UPDATE
DELETE
JOIN /*(using references like the KooID above)*/
WHERE /*(using filter expressions)*/
正如您所提到的,您的UI实际上能够读取相同的数据模式UI,并基于从数据库读取的POCO实例填充它。只要您的应用程序完全面向数据,而不需要额外的业务规则或用户界面流程,这一切都没有问题。为了返回最终文本,我提出了我的解决方案:
createPROCEDURE [dbo].[Helper_CreatePocoFromTableName]
@tableName varchar(100)
AS
BEGIN
SET NOCOUNT ON;
declare @codeLines table (lineId int, lineText varchar(4000))
insert into @codeLines
Select rowNr = ROW_NUMBER() over(order by rowNr), PropertyColumn from (
SELECT 1 as rowNr, 'public class ' + @tableName + ' {' as PropertyColumn
UNION
SELECT rowNr =2 , '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 = 'char' THEN 'string'
WHEN DATA_TYPE = 'nchar' 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 1000 as rowNr, '} // class ' + @tableName
) as t Order By rowNr asc
declare @max int=(select max(lineId) from @codeLines)
-- assembly result
declare @i int=1
declare @res nvarchar(max)=''
while(@i<=@max)
begin
set @res = @res +(select lineText +'
' from @codeLines l where l.lineId=@i )
set @i=@i+1
end
select classCode=@res
END
createPROCEDURE[dbo]。[Helper\u CreatePocoFromTableName]
@tableName varchar(100)
作为
开始
不计数;
声明@codeLines表(lineId int,lineText varchar(4000))
插入@codeLines
选择rowNr=ROW_NUMBER()(按rowNr排序),Property Column from(
选择1作为行编号,“公共类”++@tableName++“{”作为属性列
联合
选择rowNr=2,'public'+a1.NewType+''+a1.COLUMN_NAME+'{get;set;}'作为PropertyColumn
--,*添加注释,以便获得可复制粘贴的输出
从…起
(
/*使用top是因为我是按顺序排列的。
为子查询排序的唯一方法是在其上放置一个top*/
选择前100%
列名称,
数据类型,
你是纳拉布吗
createPROCEDURE [dbo].[Helper_CreatePocoFromTableName]
@tableName varchar(100)
AS
BEGIN
SET NOCOUNT ON;
declare @codeLines table (lineId int, lineText varchar(4000))
insert into @codeLines
Select rowNr = ROW_NUMBER() over(order by rowNr), PropertyColumn from (
SELECT 1 as rowNr, 'public class ' + @tableName + ' {' as PropertyColumn
UNION
SELECT rowNr =2 , '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 = 'char' THEN 'string'
WHEN DATA_TYPE = 'nchar' 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 1000 as rowNr, '} // class ' + @tableName
) as t Order By rowNr asc
declare @max int=(select max(lineId) from @codeLines)
-- assembly result
declare @i int=1
declare @res nvarchar(max)=''
while(@i<=@max)
begin
set @res = @res +(select lineText +'
' from @codeLines l where l.lineId=@i )
set @i=@i+1
end
select classCode=@res
END