从OleDb数据库读取/写入DataTable LINQ

时间:2010-04-16 21:54:28

标签: linq datatable insert oledb

我目前的项目是从OleDbDatabase和.CSV文件中获取信息,并将其全部放入更大的OleDbDatabase

我目前已经从.CSV文件中读取了我需要的所有信息,并且OleDbDatabase读入了DataTables ....它变得毛茸茸的是将所有信息写回另一个OleDbDatabase。

现在我当前的方法是做这样的事情:

    OleDbTransaction myTransaction = null;

    try
    {
        OleDbConnection conn = new OleDbConnection("PROVIDER=Microsoft.Jet.OLEDB.4.0;" +
                                                   "Data Source=" + Database);
        conn.Open();
        OleDbCommand command = conn.CreateCommand();
        string strSQL;

        command.Transaction = myTransaction;

        strSQL = "Insert into TABLE " +
                 "(FirstName, LastName) values ('" +
                 FirstName + "', '" + LastName + "')";

        command.CommandType = CommandType.Text;
        command.CommandText = strSQL;

        command.ExecuteNonQuery();

        conn.close();

    catch (Exception)
        {
            // IF invalid data is entered, rolls back the database
            myTransaction.Rollback();
        }

当然,这是非常基本的,我正在使用SQL命令将我的事务提交到连接。我的问题是我能做到这一点,但我有大约200个字段需要插入几个表。如果这是唯一的出路,我愿意做腿部工作。但我觉得有一种更简单的方法。 LINQ中有什么可以帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:5)

如果DataTable中的列名与目标表中的列名完全匹配,那么您可以使用OleDbCommandBuilder(警告:我尚未对此进行测试)。您可能遇到问题的一个方面是源数据表的数据类型与目标表的数据类型不匹配(例如,如果源列数据类型都是字符串)。

修改 我以多种方式修改了原始代码。首先,我切换到在DataTable上使用Merge方法。这使我可以跳过循环中的LoadDataRow

using ( var conn = new OleDbConnection( destinationConnString ) )
{
    //query off the destination table. Could also use Select Col1, Col2..
    //if you were not going to insert into all columns.
    const string selectSql = "Select * From [DestinationTable]";

    using ( var adapter = new OleDbDataAdapter( selectSql, conn ) )
    {
        using ( var builder = new OleDbCommandBuilder( adapter ) )
        {
            conn.Open();

            var destinationTable = new DataTable();
            adapter.Fill( destinationTable );

            //if the column names do not match exactly, then they 
            //will be skipped
            destinationTable.Merge( sourceDataTable, true, MissingSchemaAction.Ignore );

            //ensure that all rows are marked as Added.
            destinationTable.AcceptChanges();
            foreach ( DataRow row in destinationTable.Rows )
                row.SetAdded();

            builder.QuotePrefix = "[";
            builder.QuoteSuffix= "]";

            //forces the builder to rebuild its insert command
            builder.GetInsertCommand();
            adapter.Update( destinationTable );
        }
    }
}

ADDITION 另一种解决方案是使用FileHelpers之类的框架来读取CSV文件并将其发布到您的数据库中。它有一个OleDbStorage DataLink用于发布到OleDb源。请参阅SqlServerStorage InsertRecord示例以了解如何(最终替换SqlServerStorage的OleDbStorage)。

答案 1 :(得分:0)

听起来你需要将许多.mdb和.csv合并到一个.mdb中。这个答案正在运行,并且您可以使用SQL Server。如果不这样做,请考虑下载SQL Express。

使用SQL Server充当多个数据源与目标数据存储区之间的代理。将每个数据源编写为插入SQL Server保留表的脚本。将所有数据加载到保留表后,执行最终推送到目标Access数据存储区。

请考虑以下步骤:

  • 在SQL Server中,为导入的CSV数据创建保留表。

    CREATE TABLE CsvImport     (CustomerID smallint,     LastName varchar(40),     BirthDate smalldatetime)

  • 创建一个存储过程,其作业是读取给定的CSV文件路径,并插入到SQL Server表中。

    CREATE PROC ReadFromCSV      @CsvFilePath varchar(1000)     如     块     INSERT CsvImport     FROM @CsvFilePath - 'c:\ some.csv'     WITH     (     FIELDTERMINATOR =',', - 您自己的特定终结符应该在这里     ROWTERMINATOR ='\ n'     )     GO

  • 创建一个脚本,为磁盘上的每个.csv文件调用此存储过程。也许一些Excel技巧或文件系统dir管道命令可以帮助您创建这些语句。


exec ReadFromCSV 'c:\1.csv

  • 对于每个.mdb 数据源,请创建临时链接服务器。


    DECLARE @MdbFilePath varchar(1000);     SELECT @MdbFilePath ='C:\ MyMdb1.mdb';     EXEC master.dbo.sp_addlinkedserver @server = N'MY_ACCESS_DB_',@ srvproduct = N'Access',@ provider = N'Microsoft.Jet.OLEDB.4.0',@ datasrc = @ MdbFilePath

-- grab the relevant data
--your data's now in the table...
INSERT CsvImport(CustomerID, 

SELECT [CustomerID]
  ,[LastName]
  ,[BirthDate]
FROM [MY_ACCESS_DB_]...[Customers]

--remove the linked server 
EXEC master.dbo.sp_dropserver @server=N'MY_ACCESS_DB_', @droplogins='droplogins'
  • 完成将数据导入该保留表后,在SQL Server实例中创建链接服务器。这是目标数据存储区。 {1}将SQL Server中的数据导入Access。


    EXEC master.dbo.sp_addlinkedserver @server = N'MY_ACCESS_TARGET',@ srvproduct = N'Access',@ provider = N'Microsoft.Jet.OLEDB.4.0',@ datasrc ='C:\ Target.mdb'

SELECT