Dapper 提供者依赖参数令牌

Dapper provider dependant parameter token

有没有办法为不同的提供商编写参数化sql?

示例:

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

这适用于 oracle 提供程序,但 MsSql 需要“@id”作为参数。

Dapper 常见问题解答说:

It's your job to write the SQL compatible with your database provider.

但是怎么办?目前我们有以下解决方法:

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

但是用更大的 SQL 写起来真的很难看。

有没有办法让所有提供者都拥有一个令牌?

"Is there a way to have one token for all providers?"

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

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

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

"But that's really ugly to write in larger SQL's".

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

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

您可以更进一步,对带引号的标识符执行相同的操作。你可以传递类似的东西:

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

让它像

一样出来

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

一切取决于供应商。如果您想在某些自定义基础提供程序 class 上动态构建查询,您可以打开一个初始连接并存储所有提供程序特定的数据。您不会希望每次使用连接时都调用 DbConnection.GetSchema

SQL 服务器:

甲骨文: