这可能是一个古老而又好吃的东西。我正在使用System.Data.Common作为可互换的Oracle/SQL Server/SQLite数据访问库。在构造函数中,我使用连接字符串名称并使用它来确定基础提供程序类型。我这样做的原因是为每个提供者处理不同的IDbParameter命名约定。例如,Oracle喜欢:参数,而SQL Server和SQLite像@parameter。默认是?以涵盖Oledb。使用System.Data.Common的参数命名
问题:这一切都是不必要的,是否有一些简单的东西我错过了,应该简单地照顾这个?如果我的IDbCommand.CommandText =“选择ID,名称来自my.table其中id =:id”我是否覆盖?现在我只是采用?作为默认值,然后在执行命令之前RegEx'ing我的方式到正确的参数标识符。
谢谢。
/// <summary>
/// Initializes a new instance of the <see cref="RelationalGateway"/> class.
/// </summary>
/// <remarks>You must pass in the name of the connection string from the application configuration
/// file rather than the connection string itself so that the class can determine
/// which data provider to use, e.g., SqlClient vs. OracleClient.</remarks>
public RelationalGateway(string connectionStringName)
{
if (string.IsNullOrEmpty(connectionStringName)) throw new ArgumentNullException("connectionStringName");
if (ConfigurationManager.ConnectionStrings[connectionStringName] == null ||
ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString.Length == 0 ||
ConfigurationManager.ConnectionStrings[connectionStringName].ProviderName.Length == 0)
{
throw new InvalidOperationException(string.Format(
"The configuration file does not contain the {0} connection ",
connectionStringName) +
"string configuration section or the section contains empty values. Please ensure the " +
"configuration file has the appropriate values and try again.");
}
_connectionString = ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString;
_providerName = ConfigurationManager.ConnectionStrings[connectionStringName].ProviderName;
_theProvider = DbProviderFactories.GetFactory(_providerName);
_adapter = _theProvider.CreateDataAdapter();
//GetConnection();
DetermineProviderSpecificParameters();
}
DetermineProviderSpecificParameters位基本上算出“?”或“:”或“@”或其他。
UPDATE 这里是我是如何处理的细节迄今:
得到正确的参数字符串:
私人无效DetermineProviderSpecificParameters(){ // 检查支持的提供商。这样可以正确创建空间范围限制 的参数化查询。 string shortName = _providerName.Substring(_providerName.LastIndexOf(“。”)+ 1);
switch (shortName) { case "SqlClient": _param = "@"; _ql = "["; _qr = "]"; break; case "SQLite": _param = "@"; _ql = string.Empty; _qr = string.Empty; break; case "OracleClient": _param = ":"; _ql = string.Empty; _qr = string.Empty; break; default: _param = "?"; _ql = string.Empty; _qr = string.Empty; break; } }
调用一个小帮手之前,我执行每个命令“cleanify”或“parameterific”,或无论我们称之为半称职的黑客:
private void MakeProviderSpecific(IDbCommand command) { foreach (IDataParameter param in command.Parameters) { param.ParameterName = GetProviderSpecificCommandText(param.ParameterName); } command.CommandText = GetProviderSpecificCommandText(command.CommandText); }
,这就要求一个小的正则表达式要做的事:
public string GetProviderSpecificCommandText(string rawCommandText) { return Regex.Replace(rawCommandText, @"\B\?\w+", new MatchEvaluator(SpecificParam)); }
呸。仍在寻找一个相对简单的解决方案,但迄今为止的建议无疑是值得赞赏的
不确定,但做你正在做的是NHibernate的一个选项。 – Amy 2009-08-10 20:21:20
我为其他项目使用NHibernate,但这是我的其他开发人员使用的实用程序库,使他们有一个快速但不太脏的Db访问方法。此外,我将这作为我的代码的核心,用于反开源的客户端。是的,我手卷数据访问代码的次数比我想象的要多! :-( – Dylan 2009-08-10 21:55:32