Domanda

Attualmente sto sviluppando un'applicazione generatore di query, in fondo, una semplice interfaccia grafica che dovrebbe consentire agli utenti senza alcuna conoscenza di SQL per definire varie query su un database (si unisce, SELECT, INSERT, UPDATE, DELETE). Userò .NET 3.5. La mia applicazione dovrebbe supportare più database, dovrebbe funzionare con MS-SQL Server, MySQL e Oracle, quindi mi apprezzerebbe eventuali suggerimenti o collegamenti a lezione pertinenti su come progettare un DAL fornitore indipendente .

L'utente selezionerà un server di database, un database sul server corrente, fornire le credenziali di connessione, scegliere varie tabelle, definire le query (utilizzando una serie di caselle combinate) e, infine, eseguire le query se sono validi. Naturalmente, nel DAL io voglio avere metodi per ogni fornitore di DB. Sto pensando qualcosa sulle linee del modello di fabbrica.

Nota:. Si tratta di un progetto scolastico semplice, quindi non sono interessati alla sicurezza o le prestazioni delle query risultanti

UPDATE: Dopo qualche ricerca più e con l'ingresso molto prezioso che hai fornito, ho deciso di utilizzare DbProviderFactory. ORM sarebbe interessante, ma dal momento voglio solo una Query Analyzer / builder, non vedo il punto di usare uno. Così, le sarei grato se mi puntare a un tutorial dettagliato su come utilizzare DbProviderFactory e le classi associate.

È stato utile?

Soluzione

mi consiglia di utilizzare la classe System.Data.Common.DbProviderFactories per generare le classi ADO.NET generiche.

Come si trova più provider .NET per database che si desidera supportare, semplicemente cadere la DLL provider nel percorso della app e aggiungere un riferimento alla DbProviderFactory del provider nel file app.config. Si può avere all'utente di selezionare il provider da utilizzare.

Ecco un articolo di MSDN sul tema chiamato Ottenere un DbProviderFactory (ADO. NET)

Ho usato questo approccio prima e stato in grado di supportare MSSQL e SQLite nello stesso progetto con una modifica alla configurazione minore.

Non è sicuro, se funzionerà anche per un'applicazione generatore di query anche se ...

Altri suggerimenti

devo dire che la modifica di una query ragionevolmente complesso visivamente è molto ingombrante. E consentendo agli utenti di inserire / cancellare dati utilizzando visual designer è un certo modo di girare in un piede. Una versione di dimensioni-down di Management Studio, conoscenza di SQL di base più utente del server limitato farà un lavoro molto migliore.

Se siete ancora inclini a progettare questa applicazione, avrete bisogno di NHibernate. Più precisamente, Criteri query farà il lavoro, dato che fanno abbastanza vicino a ciò che è necessario.

Potreste essere sorpresi, ma molto semplice DAL fornitore indipendente può essere raggiunto con la pianura vecchio DataSet e DataTable .

Credo ADO.NET Entity Framework (disponibile dal .NET 3.5 SP1) è una scelta ideale in quanto praticamente astrae database SQL-dipendente con il suo linguaggio Entity SQL.

La maggior parte qualsiasi ORM (Object-Relational Mapper) saprà parlare con una varietà di tipi di database.

Per quanto riguarda consentendo agli utenti di costruire le proprie domande: è necessario essere molto attenti a questo. Non è tanto che gli utenti possono creare query dannosi (anche se questo può essere un problema) così com'è incidente. E 'sorprendentemente facile da scrivere una query che utilizzerà tutte le risorse del server disponibili e creare un denial efficace del servizio per il database.

Non sono sicuro se questo aiuta con la vostra ricerca, ma una cosa che ho imparato piuttosto recente e ha preso a cuore è quello di avere implementazione unico identificativo del modello di dati si propaga direttamente al di fuori dello strato di dati, ma per essere avvolto in un astrazione. Per esempio, qui è un interfaccia che avvolge identificativo di un modello:

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);
}

Il tuo livello di logica di business, che può avere in passato passato intorno ints come identificatori univoci (ad esempio, da una colonna di identità nella tabella del database), è ora passato come ad esempio:

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

Il tuo livello di dati avrà quindi una classe che implementa IModelIdentifier<Person> e popola il suo tipo di dati interno con identificativo univoco del modello fisico. Questa isola il vostro livello di business da eventuali modifiche si possono avere a livello di dati, come ad esempio sostituire il int identificatori chiave con Guids.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top