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

问题描述:

我当前的项目是从OleDbDatabase和.CSV文件获取信息,并将其全部放入更大的OleDbDatabase从OleDb数据库读取/写入数据表LINQ

我目前从两个.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中有什么可以帮助我解决这个问题吗?

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

加成另一种解决方法是使用一个框架像FileHelpers读取CSV文件,并张贴到你的数据库。它确实有一个OleDbStorage DataLink用于发布到OleDb源文件中。请参阅SqlServerStorage InsertRecord示例以了解如何(最终将OleDbStorage替换为SqlServerStorage)。

+0

目前我有一个类似于此的方法,但工作稍好。这似乎仍然sl,不驯,但它与我所遇到的解决方案类似。我试图找出一些更清洁的东西。 – jsmith 2010-04-20 13:41:40

+0

@jsmith - 你为什么认为它马虎?如果不使用外部库,“更干净”的解决方案会是什么样子?任何其他方法都需要循环遍历列,构建插入语句,然后循环遍历列和行并执行插入操作。海事组织,这是非常麻烦,需要更多的代码。我已更新我的帖子,建议您可能会发现“清洁”的FileHelpers。它当然应该使解析CSV更容易。 – Thomas 2010-04-20 14:51:20

+0

@托马斯 - 我不知道为什么我认为它马虎。 “这似乎马虎”是我说的。我不知道是否是这样,这就是我问这个问题的原因。如果我知道一个“更清洁”的解决方案,我不会要求一个。我只是试图找到最好的解决方案。现在,就是这样,但它只是觉得它可能会更好。不过,我觉得我错了。 – jsmith 2010-04-20 14:54:52

这听起来像你有很多.mdb和.csv,你需要合并成一个单一的.mdb。这个答案正在运行,并且你有SQL Server可用。如果你不这样做,那么考虑下载SQL Express。

使用SQL Server充当多个数据源和目标数据存储之间的代理。将每个数据源脚本作为插入到SQL Server持有表中的脚本。将所有数据加载到保留表中时,执行最终压入目标Access数据存储。

考虑采用以下步骤:

  • 在SQL Server上,创建临时表为导入CSV数据。

CREATE TABLE CsvImport (客户ID SMALLINT, 姓氏VARCHAR(40), 出生日期SMALLDATETIME)

  • 创建一个存储过程,他们的工作将是阅读给定的CSV文件路径,并插入到一个SQL Server表。

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

  • 创建一个脚本来调用这个S tored proc 对于您在磁盘上的每个.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',@提供商= 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实例中创建链接服务器。这是目标数据存储。 SELECT将数据从SQL Server转换为Access。


EXEC master.dbo.sp_addlinkedserver @server = N'MY_ACCESS_TARGET '@ srvproduct = N'Access',@提供商= N'Microsoft.Jet.OLEDB.4.0' ,@ DATASRC =' C: \ Target.mdb'

INSERT INTO [MY_ACCESS_TARGET]...[Customer] 
      ([CustomerID] 
      ,[LastName] 
      ,[BirthDate]) 
SELECT Customer, 
     LastName, 
     BirthDate 
FROM  CsvImport