Чтение / запись данных в и из базы данных OleDb LINQ - PullRequest
1 голос
/ 17 апреля 2010

Мой текущий проект состоит в том, чтобы взять информацию из файлов 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 ]

6 голосов
/ 20 апреля 2010

Если имена столбцов в DataTable точно совпадают с именами столбцов в таблице назначения, вы можете использовать OleDbCommandBuilder (Внимание: я еще не проверял это). Одна из проблем, с которой вы можете столкнуться, - это если типы данных исходной таблицы данных не совпадают с типами таблицы назначения (например, если все типы данных исходного столбца являются строками).

EDIT Я пересмотрел свой оригинальный код несколькими способами. Сначала я переключился на использование метода Merge в DataTable. Это позволило мне пропустить использование 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 , чтобы увидеть, как (в конце замените OleDbStorage на SqlServerStorage).

0 голосов
/ 20 апреля 2010

Похоже, у вас есть много .mdb и .csv, которые вам нужно объединить в один .mdb. Этот ответ работает с этим предположением, и что у вас есть доступ к SQL Server. Если вы этого не сделаете, рассмотрите возможность загрузки SQL Express.

Использование SQL Server в качестве посредника между несколькими источниками данных и целевым хранилищем данных. Сценарий каждого источника данных как вставка в таблицу хранения SQL Server. Когда все данные загружены в таблицу хранения, выполните окончательное добавление в целевое хранилище данных Access.

Рассмотрим эти шаги:

  • В SQL Server создайте таблицу хранения для импортированных данных CSV.

CREATE TABLE CsvImport (CustomerID smallint, LastName varchar (40), Дата рождения smalldatetime)

  • Создайте сохраненный процесс, задачей которого будет чтение заданного пути к файлу CSV, и вставьте его в таблицу SQL Server.

CREATE PROC ReadFromCSV @CsvFilePath varchar (1000) КАК BULK ВСТАВИТЬ CsvImport FROM @CsvFilePath - 'c: \ some.csv' С ( FIELDTERMINATOR = ',', - ваши собственные определенные терминаторы должны идти сюда ROWTERMINATOR = '\ n' ) GO

  • Создайте сценарий для вызова этой сохраненной процедуры для каждого файла .csv , который имеется на диске. Возможно, некоторые хитрости Excel или файловая система dir пипетированных команд могут помочь вам создать эти операторы.


exec ReadFromCSV 'c:\1.csv

  • Для каждого источника данных .mdb создайте временный связанный сервер.


ОБЪЯВИТЬ @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. Это целевое хранилище данных. 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
...