从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)。
这听起来像你有很多.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
目前我有一个类似于此的方法,但工作稍好。这似乎仍然sl,不驯,但它与我所遇到的解决方案类似。我试图找出一些更清洁的东西。 – jsmith 2010-04-20 13:41:40
@jsmith - 你为什么认为它马虎?如果不使用外部库,“更干净”的解决方案会是什么样子?任何其他方法都需要循环遍历列,构建插入语句,然后循环遍历列和行并执行插入操作。海事组织,这是非常麻烦,需要更多的代码。我已更新我的帖子,建议您可能会发现“清洁”的FileHelpers。它当然应该使解析CSV更容易。 – Thomas 2010-04-20 14:51:20
@托马斯 - 我不知道为什么我认为它马虎。 “这似乎马虎”是我说的。我不知道是否是这样,这就是我问这个问题的原因。如果我知道一个“更清洁”的解决方案,我不会要求一个。我只是试图找到最好的解决方案。现在,就是这样,但它只是觉得它可能会更好。不过,我觉得我错了。 – jsmith 2010-04-20 14:54:52