Crie driver personalizado para system.data.common
-
20-09-2019 - |
Pergunta
Fundo:
Nosso aplicativo C# gera e executa consultas para vários tipos de bancos de dados (Oracle, SQL Server, MySQL), mas um requisito surgiu para aplicá -los também a um formato de arquivo proprietário.
- O espaço para nome usado até agora é System.data.common.
- As consultas que precisamos aplicar são não triviais (seleções aninhadas, aliases em, de métodos de substring e concatenações de string)
Inicialmente convertemos o conteúdo do arquivo proprietário para CSV, para o qual existe o motorista {Driver de texto da Microsoft ( *.txt; *.csv)}. No entanto, o cliente exigiu que nenhum arquivo temp fosse gerado e tudo deve acontecer na memória.
Criar um driver ODBC para consultar o arquivo diretamente parece exigente muito tempo. Portanto, estamos pensando em criar um driver (possivelmente ODBC), no qual "incorporaremos" o driver SQLite ODBC. Dentro desse driver, podemos carregar o conteúdo dos arquivos CSV no banco de dados "in-memória" e encaminhar a consulta ao driver ODBC interno.
Minhas perguntas:
- Essa solução parece viável?
- Por onde devemos começar para criar um driver ODBC do zero?
Obrigado
Solução
Se usar o SQLite como back -end é uma possibilidade, não consigo ver por que você não poderia usar um provedor de ADO .NET para o seu banco de dados SQLite como System.data.sqlite.
Pelo seu comentário, acho que você está em vigor usando o provedor .NET do ODBC ADO para todas as conexões do banco de dados (System.data.odbc). Se você precisar manter o mesmo esquema, um provedor personalizado do ODBC é o caminho a percorrer (mas então é um desenvolvimento nativo simples e bastante doloroso, acredito).
Outra maneira de ir seria adicionar um terceiro parâmetro ao seu banco de dados (os dois primeiros são o SQL e a string de conexão): o provedor ADO .NET a ser usado (como se fosse deve ser feito em arquivos de configuração, Veja o providerName
atributo). Dessa forma, você pode usar qualquer provedor ADO .NET disponível.
Em seguida, você pode envolver o provedor SQLite em seu próprio provedor de ADO .NET personalizado, que pode incluir a geração e a população do sqlite db. Vantagem desta solução: Pure gerenciado .NET.
Outras dicas
A solicitação do cliente é estranha. Sempre haverá arquivos envolvidos, você está lendo um arquivo.
Se eles querem suas coisas na memória (novamente um cliente estranho) coloque os CSVs em um disco RAM:http://members.fortunecity.com/ramdisk/ramdisk/ramdriv001.htm
Construir e o ODBC Drive é um empreendimento que não é de trival se você se preocupa com desempenho e estabilidade.
Eu acho que sua solução consome tempo. Você pode encontrar soluções existentes para o que está tentando fazer. Aqui estão poucas alternativas.
Por que não tentar o LINQ para enviar o arquivo de texto/CSV?
- http://www.codeproject.com/kb/linq/linqtocsv.aspx
- http://blogs.msdn.com/ericwhite/archive/2008/09/30/linq-to-text-and-linq-to-csv.aspx
Ambas as soluções estão na memória.
Outra idéia é que você pode exportar o arquivo em XML em vez de CSV ou texto (sempre prefiro exportar para XML quando preciso processar no meu código). Do que você usa o System.xml ou o LINQ para XML para executar operações.
Se você não estiver restrito para não criar arquivos temporários, poderá tentar usar o modo de memória do sqlite. Aqui está uma amostra de string de conexão para ela (fonte):
Data Source=:memory:;Version=3;New=True;
Na minha opinião, isso é mais simples do que construir fornecedor completo. $