有没有办法为不同的提供程序编写参数化的SQL?
例:
connection.QuerySingle<string>("select name from user where id = :id", new {id = 4});
这适用于oracle提供程序,但MsSql需要“@id”作为参数。
Dapper FAQ说:
编写与数据库提供程序兼容的SQL是你的工作。
但是怎么样?目前我们有以下解决方法:
$".. where id = {db.ParamToken}id"
但是在较大的SQL中编写它真的很难看。
有没有办法为所有提供商提供一个令牌?
“有没有办法为所有提供商提供一个令牌?”
是的,但它需要一些设置。您可以从现有的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
。