Pergunta

Atualmente, estou desenvolvendo um aplicativo construtor de consulta, basicamente, uma interface gráfica simples que deve permitir que usuários sem conhecimento de SQL para definir várias consultas em um banco de dados (junções, SELECT, INSERT, UPDATE, DELETE). I será usando .NET 3.5. Meu aplicativo deve suportar múltiplos bancos de dados, ele deve funcionar com o MS-SQL Server, MySQL e Oracle, então eu gostaria de receber quaisquer sugestões ou links para leitura relevante sobre como criar um DAL independente de fornecedor .

O usuário irá selecionar um servidor de banco de dados, um banco de dados no servidor atual, forneça as credenciais de conexão, escolher várias tabelas, definir consultas (utilizando uma série de caixas de combinação) e, finalmente, executar as consultas se eles são válidos. Claro, na DAL eu quero ter métodos para cada provedor DB. Estou pensando em algo sobre as linhas do padrão de fábrica.

Nota:. Este é um projeto simples escola, então eu não estou interessado na segurança ou desempenho das consultas resultantes

UPDATE: Depois de mais algumas pesquisas e com a entrada de muito valioso que você forneceu, eu decidi usar DbProviderFactory. ORM seria interessante, mas desde que eu só quero uma consulta analisador / construtor, eu não vejo o ponto de usar um. Então, eu apreciaria se você me apontar para um tutorial detalhado sobre como usar DbProviderFactory e as classes associadas.

Foi útil?

Solução

Eu recomendo usar a classe System.Data.Common.DbProviderFactories para gerar classes ADO.NET genérico.

Como você encontrar mais .NET fornecedores para bancos de dados que você deseja suporte, simplesmente soltar a DLL provedor no caminho do aplicativo e adicione uma referência para o DbProviderFactory do provedor no arquivo app.config. Você pode ter o usuário selecione o provedor ao uso.

Aqui está um artigo MSDN sobre o tema chamado A obtenção de uma DbProviderFactory (ADO. NET)

Eu usei essa abordagem antes e foi capaz de suportar MSSQL e SQLite no mesmo projeto com uma mudança de configuração menor.

Não tenho certeza, se ele vai funcionar tão bem para um aplicativo construtor de consulta embora ...

Outras dicas

Devo dizer que editar uma consulta razoavelmente complexo visualmente é muito complicado. E permitindo aos usuários inserir / dados de exclusão usando designer visual é um caminho certo para atirar no próprio pé. Um usuário do servidor porte-down versão do Management Studio, o conhecimento de SQL básico mais restrito vai fazer um trabalho muito melhor.

Se você ainda está inclinado a projetar este aplicativo, você vai precisar NHibernate. Mais precisamente, Critérios consultas farão o trabalho, uma vez que o mapa bastante perto do que você precisa.

Você pode se surpreender, mas uma DAL independente de fornecedor muito simples pode ser conseguido com planície antiga DataSet e DataTable .

Eu acho ADO.NET Entity Framework (disponível desde o .NET 3.5 SP1) é uma ótima escolha, pois praticamente abstrai SQL dependente do banco de dados com sua linguagem entidade SQL.

A maioria dos qualquer ORM (Object-Relational Mapper) vai saber como falar com uma variedade de tipos de banco de dados.

Como para permitir que os usuários criem suas próprias consultas: você precisa ter muito cuidado com isso. Não é tanto que os usuários podem criar consultas maliciosos (embora isso pode ser um problema), pois é acidente. É surpreendentemente fácil de escrever uma consulta que irá utilizar todos os recursos de servidor disponíveis e criar uma negação eficaz de serviço para o seu banco de dados.

Eu não tenho certeza se isso ajuda com sua busca, mas uma coisa eu aprendi bastante recentemente e levou a sério é ter aplicação o identificador exclusivo do modelo de dados se propagam diretamente fora da camada de dados, mas para ser envolto em um abstração. Por exemplo, aqui é uma interface que envolve identificador de um modelo:

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

A sua camada de lógica de negócios, o que pode ter no passado passou em torno ints como identificadores únicos (por exemplo, a partir de uma coluna de identidade na tabela de banco de dados), agora é passado como tal:

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

A sua camada de dados terá, então, uma classe que implementa IModelIdentifier<Person> e preenche seu tipo de dados interno com o identificador exclusivo do modelo físico. Isso isola a sua camada de negócios de todas as mudanças que você pode ter na camada de dados, como substituir seus identificadores de chave int com Guids.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top