這可能是一個古老而又好吃的東西。我正在使用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