代码之家  ›  专栏  ›  技术社区  ›  jsmith

在OLEDB数据库LINQ中读/写数据表

  •  1
  • jsmith  · 技术社区  · 16 年前

    我现在的项目是从 OleDbDatabase 以及.csv文件,并将其全部放入一个更大的 OLEDB数据库 .

    我目前已经从.csv文件和 OLEDB数据库 进入之内 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个字段需要插入到多个表中。如果这是唯一的办法,我愿意做腿部工作。但我觉得有一个更简单的方法。林肯有什么可以帮我解决这个问题的吗?

    2 回复  |  直到 16 年前
        1
  •  5
  •   Thomas    16 年前

    如果 DataTable 与目标表中的列名完全匹配,则可以使用 OleDbCommandBuilder (警告:我还没有测试过这个)。如果源数据表的数据类型与目标表的数据类型不匹配(例如,如果源列数据类型都是字符串),则可能会遇到问题。

    编辑 我以多种方式修改了我的原始代码。首先,我切换到对数据表使用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 用于发布到OLEDB源的数据链接。见 SqlServerStorage InsertRecord 示例以了解如何(最后用oledbstorage替换sqlserverstorage)。

        2
  •  0
  •   p.campbell    16 年前

    听起来好像有很多.mdb和.csv需要合并到一个.mdb中。这个答案是在这个假设下运行的,并且您有可用的sql server。如果没有,请考虑下载sql express。

    使用sql server充当代理 在多个数据源和目标数据存储之间。将每个数据源编写为SQL Server存放表的插入。当所有数据都加载到保持表中时,执行最后一次推送到目标访问数据存储中。

    考虑以下步骤:

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

    创建csvimport表 (客户ID smallint, 姓varchar(40), 生日smalldatetime)

    • 创建一个存储过程,其任务是读取给定的csv文件路径,并插入到sql server表中。

    创建过程readfromcsv @csvfilepath变量字符(1000) AS 体积 插入csvimport 从@csvfilepath--“c:.some.csv” 用 ( fieldTerminator=',',--您自己的特定终结符应该放在这里 行终止符='\n' ) 去

    • 创建脚本以调用此存储过程 对于每个.csv文件 你的磁盘上有。也许是一些优秀的诡计或文件系统 dir 管道命令可以帮助您创建这些语句。


    exec ReadFromCSV 'c:\1.csv

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


    声明@mdbfilepath varchar(1000); 选择@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实例中创建链接服务器。这是目标数据存储。 SELECT 数据从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'

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