Dies ist wahrscheinlich ein Oldie-aber-Goodie. Ich verwende System.Data.Common für eine austauschbare Oracle/SQL Server/SQLite-Datenzugriffsbibliothek. Während des Konstruktors nehme ich den Namen der Verbindungszeichenfolge und verwende diesen, um den zugrunde liegenden Providertyp zu bestimmen. Der Grund dafür besteht darin, die unterschiedlichen IDbParameter-Namenskonventionen für jeden Provider zu behandeln. Zum Beispiel mag Oracle: Parameter, SQL Server und SQLite wie @Parameter. Der Standardwert ist? um Oledb zu decken.Parameter Benennung mit System.Data.Common
Frage: Ist das alles unnötig und gibt es eine einfache Sache, die ich vermisse, sollte sich das einfach kümmern? Wenn meine IDbCommand.CommandText = "ID auswählen, Name von meiner.Tabelle mit ID =: ID" bin ich abgedeckt? Für jetzt nehme ich nur an? als Standard und dann RegEx'ing mein Weg zur richtigen Parameter-Kennung vor dem Ausführen des Befehls.
Danke.
/// <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();
}
Das Bit "DetermineProviderSpecificParameters" kommt im Prinzip auf "?" oder ":" oder "@" oder etwas anderes.
Holen Sie sich den richtigen Parameter string::
private void DetermineProviderSpecificParameters() { // unterstützten Anbieter prüfen bisher
UPDATE Hier ist, wie ich die Details bin Handhabung. Dies ist so, dass parametrisierte Abfragen zur Begrenzung // durch räumliche Ausdehnung korrekt erstellt werden. Zeichenfolge 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; } }
Anruf ein kleiner Helfer, bevor ich jeden Befehl zu „cleanify“ ausführen oder „parameterific“ es oder aber wir diesen halbherzig Hack nennen:
private void MakeProviderSpecific(IDbCommand command) { foreach (IDataParameter param in command.Parameters) { param.ParameterName = GetProviderSpecificCommandText(param.ParameterName); } command.CommandText = GetProviderSpecificCommandText(command.CommandText); }
Und das nennt ein wenig regex
public string GetProviderSpecificCommandText(string rawCommandText) { return Regex.Replace(rawCommandText, @"\B\?\w+", new MatchEvaluator(SpecificParam)); }
Yuck: zu tun zu tun. Immer noch auf der Suche nach einer relativ einfachen Lösung, aber die bisherigen Ratschläge werden sicherlich geschätzt.
Nicht sicher, aber eine Möglichkeit zu tun, was Sie gerade tun, ist NHibernate. – Amy
Ich benutze NHibernate für andere Projekte, aber dies ist eine Utility-Bibliothek für meine anderen Entwickler zu verwenden, die ihnen einen schnellen, aber nicht zu dreckigen Db-Zugang Ansatz gibt. Außerdem benutze ich dies als den Kern meines Codes für Kunden, die Anti-Open-Source sind. Ja, ich gebe den Datenzugriffscode öfter ein, als ich denken kann! :-( – Dylan