为 System.Data.Common 创建自定义驱动程序
背景:
我们的 C# 应用程序生成并执行对多种类型的数据库(Oracle、SQL Server、MySQL)的查询,但还要求将它们应用于专有文件格式。
- 到目前为止使用的命名空间是System.Data.Common。
- 我们需要应用的查询并不简单(嵌套 SELECT、FROM 中的别名、子字符串方法和字符串连接)
我们最初将专有文件的内容转换为 CSV,为此存在驱动程序 {Microsoft Text Driver ( *.txt; *.csv)}。但是,客户端要求不生成临时文件,并且一切都应该在内存中发生。
创建 ODBC 驱动程序来直接查询文件似乎太耗时。因此,我们正在考虑创建一个驱动程序(可能是 ODBC),我们将在其中“嵌入”SQLITE ODBC 驱动程序。在该驱动程序内部,我们可以将 CSV 文件的内容加载到“内存”数据库中,然后将查询转发到内部 ODBC 驱动程序。
我的问题:
- 这个解决方案看起来可行吗?
- 为了从头开始创建 ODBC 驱动程序,我们应该从哪里开始?
谢谢
Background:
Our C# application generates and executes queries to several types of databases (Oracle, SQL Server, MySQL), but a requirement came up to also apply them to a proprietary file format.
- The namespace used until now is System.Data.Common.
- The queries we need to apply are non-trivial (nested SELECTs, aliases in FROM, substring methods and string concatenations)
We initially converted the contents of the proprietary file to CSV, for which there exists the Driver {Microsoft Text Driver (*.txt; *.csv)}. However, the client required that no temp files are generated, and everything should happen in-memory.
Creating an ODBC driver to query the file directly seems too time-demanding. So, we are considering creating a driver (possibly ODBC), in which we will "embed" the SQLITE ODBC driver. Inside that driver, we can load the contents of the CSV files in the "in-memory" database, and then forward the query to the inner ODBC driver.
My questions:
- Does this solution seem feasible?
- Where should we start in order to create an ODBC driver from scratch?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
客户的要求很奇怪。总会涉及到文件,您正在从文件中读取。
如果他们想要将数据保存在内存中(又是一个奇怪的客户),请将 CSV 放到 RAM 磁盘上:
http://members.fortunecity.com/ramdisk/RAMDisk/ramdriv001.htm
如果您关心性能和稳定性,构建和 ODBC 驱动器是一项不简单的任务。
The client request is odd. There will always be files involved, you are reading from a file.
If they want their stuff in memory (again a weird customer) put the CSVs on to a RAM Disk:
http://members.fortunecity.com/ramdisk/RAMDisk/ramdriv001.htm
Building and ODBC drive is a non-trival undertaking if you care about performance and stability.
如果可以使用 SQLite 作为后端,我真的不明白为什么你不能在 SQLite 数据库中使用 ADO .NET 提供程序,例如 系统.Data.SQLite。
根据您的评论,我认为您实际上正在使用 ODBC ADO .NET 提供程序来进行所有数据库连接 (System.Data.Odbc)。如果您需要保持相同的方案,那么自定义 ODBC 提供程序是可行的方法(但它是纯 C 本机开发,我认为相当痛苦)。
另一种方法是向数据库添加第三个参数(前两个参数是 SQL 和连接字符串):要使用的 ADO .NET 提供程序(就像 应该在配置文件中完成,请参阅
providerName
属性)。这样您就可以使用任何可用的 ADO .NET 提供程序。然后,您可以将 SQLite 提供程序包装到您自己的自定义 ADO .NET 提供程序中,其中可能包括 SQLite DB 的生成和填充。该解决方案的优点:纯托管.NET。
If using SQLite as a backend is a possibility, I cannot really see why you could not use an ADO .NET provider to your SQLite database like System.Data.SQLite.
From your comment, I think you are in effect using the ODBC ADO .NET provider for all database connections (System.Data.Odbc). If you need to keep the same scheme, then a custom ODBC provider is the way to go (but then it is plain C native development, and rather painful I believe).
Another way to go would be to add a third parameter to your DB (the first two being the SQL and the connection string) : the ADO .NET provider to be used (like it is supposed to be done in configuration files, see the
providerName
attribute). This way you could use any ADO .NET provider available.Then you could wrap the the SQLite provider into your own, custom, ADO .NET provider, that could include the generation and population of the SQLite DB. Advantage of this solution : pure managed .NET.
我认为你的解决方案很耗时。您可以找到适合您正在尝试做的事情的现有解决方案。这里有一些替代方案。
为什么不尝试 Linq to text/csv file?
两种解决方案都在内存中。
另一个想法是,您可以导出 xml 文件,而不是 csv 或文本(当我必须在代码中处理时,我总是更喜欢导出到 xml)。比您使用 System.Xml 或 Linq to Xml 来执行操作。
I think your solution is time consuming. You can find existing solutions for what you are trying to do. Here are few alternates.
Why not try Linq to text/csv file?
Both solutions are in memory.
Another idea is that, you can export file in xml instead of csv or text (I always prefer export into xml when I have to process in my code). Than you use System.Xml or Linq to Xml to perform operations.
如果你只是被限制不能创建临时文件,你可以尝试使用SQLite的内存模式。这是它的连接字符串示例(来源):
在我看来,这比构建成熟的提供程序更简单。$
If you only are restricted not to create temporary files, you may try to use in-memory mode of SQLite. Here's a sample of connection string for it (source):
To my mind, this is simpler than building full-blown provider.$