1

我正在为另一个生成相当复杂的对象树结构的程序编写插件。用户将需要从插件中导出此数据以进行分析和报告。我绝对希望他们能够导出到 MS Access 数据库,因为这将是他们创建快速和干净报告的最方便的方法。但我也想进行设置,以便轻松导出到其他数据源(XLS、XML、SQL Server 等)而无需大量重复代码。

我创建了将从树结构中填充各种数据表的递归方法。然后我可以将这些DataTables填充到DataSet中。但在那一点上,我有点迷路了。

我为ADO.NET找到的所有示例都是从拥有一些中央数据源开始的。然后,您使用连接字符串通过正确的DataProvider创建与数据的DataConnection 。之后,您可以根据是否需要将更改保存回源来获取DataReaderDataSet 。

然而,我从DataSet开始,需要从中创建一个数据源。有没有一些简单的可重用方法,我可以根据一些现有的空数据源创建一个新的DataConnection,然后用我的DataSet填充它?

例如,我可以创建一个DataConnection到一个空的 MS Access 文件。然后我可以使用我的递归方法从我的树结构中填充数据集中的各种数据表。但是我怎么能用这个生成的DataSet填充空白的访问数据库呢?

我希望有一种足够通用的方法,以便我可以通过简单地交换不同的DataProviders和/或连接字符串轻松地导出到不同的潜在数据源。

4

1 回答 1

2

You're essentially asking two separate questions here, one about inserting data without first selecting from the target table and another about keeping your persistence code database agnostic.

It's relatively easy to manually build up a data table in memory and persist it with the help of a DataAdapter and a DbCommandBuilder. The data adapter is used to synchronize the data table into the database and the command builder is used by the data adapter to automatically generate insert (and update) statements based on the select command provided.

So long as you don't need to run any complex SQL queries it should be fairly easy to keep your code database agnostic using a DbProviderFactory. It essentially hides the ADO.net provider implementation from you so that you code against the underlying interfaces in a generic way.

The following example should illustrate the above two concepts.

public static void Main()
{
    var providerName = "System.Data.OleDb";
    var connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;" +
                            "Data Source=output.mdb";
    var table = new DataTable {
                        Columns = {
                            new DataColumn("ID", typeof (int)),
                            new DataColumn("Name", typeof (string)) },
                        Rows = {
                            new object[] {1, "One"},
                            new object[] {2, "Two"} }
                    };
    SaveData(providerName, connectionString, table);
}
private static void SaveData(string providerName,
                             string connectionString,
                             DataTable table)
{
    var factory = DbProviderFactories.GetFactory(providerName);
    var connection = factory.CreateConnection();
    connection.ConnectionString = connectionString;
    var command= factory.CreateCommand();
    command.Connection = connection;
    command.CommandText = "select ID, Name from Person";
    var adapter = factory.CreateDataAdapter();
    adapter.SelectCommand = command;
    var builder = factory.CreateCommandBuilder();
    builder.DataAdapter = adapter;
    adapter.Update(table);
}

This solution only deals with persistence to databases. For exporting to Excel you can use the Jet OleDb provider (more info here) and for XML you can use XmlSerializer.

于 2009-08-27T12:18:30.710 回答