Dapper提供者相关的参数令牌

时间:2018-08-31 15:04:49

标签: c# ado.net dapper

是否可以为不同的提供程序编写参数化的sql?

示例:

connection.QuerySingle<string>("select name from user where id = :id", new {id = 4});

这将与oracle提供程序一起使用,但是MsSql需要“ @id”作为参数。

Dapper常见问题解答说:

  

编写与数据库提供程序兼容的SQL是您的工作。

但是如何?当前,我们有以下解决方法:

$".. where id = {db.ParamToken}id"

但是用较大的SQL编写确实很丑陋。

是否可以为所有提供商提供一个令牌?

1 个答案:

答案 0 :(得分:1)

  

“是否可以为所有提供商提供一个令牌?”

是的,但是需要一些设置。您可以从现有的DBConnection中检索有用的数据库提供程序特定的信息。首先从连接中检索DataSourceInformation表:

DbConnection connection = GetSomeConnection();
var infoTable = connection.GetSchema(DbMetaDataCollectionNames.DataSourceInformation);

该表将只有一行,其中包含各种提供商信息。关于参数命名,将存在名为ParameterMarkerPattern的列,该列代表用于验证参数的Regex模式字符串。如果该列中有数据,则第一个字符将是您的DbParameter标记。如果该列为空白,则ParameterMarkerFormat可以为您提供一种在构建参数名称时要应用的字符串格式。

  

“但是用较大的SQL编写确实很丑。”

如果您正在考虑直接格式化SQL,这并不能真正解决问题,并且解决方法已经比这简单得多。但是,您从DataSourceInformation获得的其他数据应该足以将您自己的字符串传递给您创建的方法,该方法将使用适当的参数替换默认的参数起始字符(例如@)提供商提供的一个:

string sql = SqlIfy("SELECT name FROM user WHERE id = @id");

您甚至可以进一步处理加引号的标识符。您可以输入以下内容:

"SELECT [Name] FROM [dbo].[SomeTable]"

它像

一样出现

SELECT "Name" FROM "dbo"."SomeTable"

全部取决于提供者。如果要在某个自定义基本提供程序类上动态构建查询,则可以打开初始连接并存储所有特定于提供程序的数据。您不想每次使用连接时都呼叫DbConnection.GetSchema

SQL Server: enter image description here

Oracle: enter image description here