0

Ich entwickle derzeit eine Abfrage-Generator-Anwendung, im Grunde eine einfache grafische Benutzeroberfläche, die es Benutzern ohne SQL-Kenntnisse ermöglichen sollte, verschiedene Abfragen auf einer Datenbank zu definieren (Joins, Auswählen, Aktualisieren , einfügen, löschen). Ich werde .Net 3.5 verwenden. Meine Anwendung sollte mehrere Datenbanken unterstützen, sie sollte mit MS-SQL Server, MySQL und Oracle arbeiten, daher würde ich mich über Hinweise oder Links zu relevanten Vorlesungen unter freuen, wie man einen Provider unabhängig DAL entwirft.So erstellen Sie einen Provider unabhängig DAL (.Net)

Der Benutzer wird einen Datenbankserver, eine Datenbank auf dem aktuellen Server auswählen, die Verbindungsanmeldeinformationen angeben, verschiedene Tabellen auswählen, Abfragen definieren (mithilfe einer Reihe von Kombinationsfeldern) und schließlich die Abfragen ausführen, wenn sie gültig sind. Natürlich möchte ich in der DAL Methoden für jeden DB-Provider haben. Ich denke etwas an die Linien des Fabrikmusters.

Hinweis: Dies ist ein einfaches Schulprojekt, daher bin ich nicht an der Sicherheit oder Leistung der resultierenden Abfragen interessiert.

UPDATE: Nach etwas mehr Forschung und mit dem sehr wertvollen Input, den Sie zur Verfügung gestellt haben, entschied ich mich, DbProviderFactory zu verwenden. ORM wäre interessant, aber da ich nur einen Abfrage-Analysator/Builder brauche, sehe ich keinen Sinn darin, einen zu verwenden. Daher würde ich mich freuen, wenn Sie mich auf ein ausführliches Tutorial zur Verwendung von DbProviderFactory und den zugehörigen Klassen hinweisen würden.

Antwort

2

Ich empfehle die Verwendung der System.Data.Common.DbProviderFactories-Klasse, generische ADO.NET-Klassen zu generieren.

Da Sie mehr .NET-Anbieter für Datenbanken finden, die Sie unterstützen möchten, löschen Sie einfach die Provider-DLL im Pfad der Anwendung und fügen Sie einen Verweis auf die DbProviderFactory des Providers in der app.config-Datei hinzu. Sie können festlegen, dass der Benutzer den zu verwendenden Anbieter auswählt.

Hier ist ein MSDN-Artikel zum Thema: Obtaining a DbProviderFactory (ADO.NET)

ich diesen Ansatz verwendet habe vor und in der Lage gewesen, MSSQL und SQLite im selben Projekt mit einer kleinen Konfigurationsänderung zu unterstützen.

nicht sicher, ob es aber für eine Query Builder App und wird funktionieren ...

+1

Wie in der Welt wird ihm das helfen? Das Abrufen der entsprechenden DbProviderFactory ist miserabel, 0,2% der Funktionalität, der komplexeste Teil wird die tatsächliche Abfragesyntax sein, die von der DbProviderFactory-Funktionalität _at all_ nicht abgedeckt wird. –

+0

Er fragte nichts über die Abfragesyntax. Er fragte nach einer Provider-unabhängigen DAL. DbProviderFactory gibt ihm ein bereits implementiertes Factory-Muster, auf dem seine DAL basieren soll. Der Mangel an Funktionalität ist darauf zurückzuführen, dass es in der Lage sein muss, mit einer Vielzahl von RDBMS zu arbeiten und somit keine der herstellerspezifischen Merkmale der Datenbanken zu verwenden. Wenn er sich an Straight Selects hält, aktualisiert, löscht und einfügt, sollte es keine Probleme geben. Aber gewährt, ORM gibt Ihnen mehr. –

+0

Wie für die Verwendung von ORM: Wenn die Anwendung hart codierte Geschäftsobjekte hat, wird es perfekt funktionieren. Aber wenn es sich bei der Anwendung um einen einfachen Query Builder/Runner ohne spezifische Domäne (wie den Query Analyzer von MS) handelt, ist ORM, soweit ich weiß, nicht viel hilfreich. Bitte korrigieren Sie mich, wenn ich falsch liege. Ich bin nicht zu 100% über die Verwendung von ORM informiert. –

0

Ich denke, ADO.NET Entity Framework (verfügbar seit .NET 3.5 SP1) ist eine gute Wahl, da es ziemlich Datenbank-abhängigen SQL mit seiner SQL-Entität abstrahiert.

+0

Ab sofort unterstützt ADO.NET EF nur das DBMS von Microsoft. –

+0

Entity funktioniert nur mit MS SQL Server. – kjv

+0

Es wurde entwickelt, um im Herzen DB-unabhängig zu sein. Ich bin mir ziemlich sicher, dass es auch EF-Provider für andere DBMS gibt (Google it). Ich bin mir nicht sicher über die Stabilität von ihnen, da ich sie noch nicht benutzt habe. –

0

Sie könnten überrascht sein, aber ein sehr einfachen Provider unabhängiger DAL kann erreicht werden durch:

plain old DataSet und Datatable.

0

Ich muss sagen, dass die Bearbeitung einer relativ komplexen Abfrage visuell sehr umständlich ist. Und es den Benutzern zu ermöglichen, Daten mit Hilfe des visuellen Designers einzufügen/zu löschen, ist eine Möglichkeit, sich in den Fuß zu schießen. Eine eingeschränkte Version von Management Studio, die Kenntnis der grundlegenden SQL-Funktionen und der eingeschränkten Serverbenutzer werden viel bessere Arbeit leisten.

Wenn Sie immer noch geneigt sind, diese App zu entwickeln, benötigen Sie NHibernate. Genauer gesagt, Criteria Queries wird den Job machen, da sie ziemlich nah an dem, was Sie brauchen, zuordnen.

0

Die meisten ORM (Object-Relational Mapper) wissen, wie man mit einer Vielzahl von Datenbanktypen kommuniziert.

Damit Benutzer ihre eigenen Abfragen erstellen können: Sie müssen sehr vorsichtig damit sein. Es ist nicht so, dass Benutzer bösartige Abfragen erstellen könnten (obwohl das ein Problem sein kann), da es ein Zufall ist. Es ist überraschend einfach, eine Abfrage zu schreiben, die alle verfügbaren Serverressourcen verwendet und einen effektiven Denial-of-Service für Ihre Datenbank erstellt.

0

Ich bin mir nicht sicher, ob dies mit Ihrem Streben unterstützt, aber eine Sache habe ich gelernt, eher vor kurzem und nahm zu Herzen Die Implementierung der eindeutigen ID Ihres Datenmodells darf nicht direkt außerhalb der Datenschicht, sondern in einer Abstraktion erfolgen. Zum Beispiel, hier ist eine Schnittstelle, die ein Modells Kennung Wraps:

public interface IModelIdentifier<T> where T : class 
{ 
    /// <summary> 
    /// A string representation of the domain the model originated from. 
    /// </summary> 
    string Origin { get; } 

    /// <summary> 
    /// The model instance identifier for the model object that this 
    /// <see cref="IModelIdentifier{T}"/> refers to. Typically, this 
    /// is a database key, file name, or some other unique identifier. 
    /// <typeparam name="KeyDataType">The expected data type of the 
    /// identifier.</typeparam> 
    /// </summary> 
    KeyDataType GetKey<KeyDataType>(); 

    /// <summary> 
    /// Performs an equality check on the two model identifiers and 
    /// returns <c>true</c> if they are equal; otherwise <c>false</c> 
    /// is returned. All implementations must also override the equal operator. 
    /// </summary> 
    /// <param name="obj">The identifier to compare against.</param> 
    /// <returns><c>true</c> if the identifiers are equal; otherwise 
    /// <c>false</c> is returned.</returns> 
    bool Equals(IModelIdentifier<T> obj); 
} 

Ihre Business-Logik-Schicht, die in der Vergangenheit um int s als eindeutige Kennungen (zum Beispiel bestanden haben kann, von einer Identitätsspalte in Ihrer Datenbanktabelle), wird nun als solche geführt:

public IPerson RetrievePerson(IModelIdentifier<IPerson> personId) 
    { 
     /// Retrieval logic here... 
    } 

Ihre Datenschicht wird dann eine Klasse, die IModelIdentifier<Person> und füllt seinen internen Datentyp mit dem physikalischen Modell des eindeutigen Kennung implementiert. Dies isoliert Ihre Business-Schicht von allen Änderungen, die Sie möglicherweise auf der Datenschicht haben, z. B. indem Sie Ihre Schlüssel-ID int durch Guid ersetzen.