是否可以为不同的提供程序编写参数化的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编写确实很丑陋。
是否可以为所有提供商提供一个令牌?
答案 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
。