我目前的项目是从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中有什么可以帮我解决这个问题吗?
答案 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数据存储区。
请考虑以下步骤:
CREATE TABLE CsvImport (CustomerID smallint, LastName varchar(40), BirthDate smalldatetime)
CREATE PROC ReadFromCSV @CsvFilePath varchar(1000) 如 块 INSERT CsvImport FROM @CsvFilePath - 'c:\ some.csv' WITH ( FIELDTERMINATOR =',', - 您自己的特定终结符应该在这里 ROWTERMINATOR ='\ n' ) GO
dir
管道命令可以帮助您创建这些语句。
exec ReadFromCSV 'c:\1.csv
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'
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