我现在正在玩这个,最终我想将CSV文件读入内存,然后将记录插入SQL数据库。应更新现有记录,添加缺失的记录。但是,不应删除新CSV中不存在的记录。
我一直在玩MSDN库中的示例。我知道SqlDataAdapter可以很快地执行批量更新。
我使用名为TempTestTable
的表创建了一个小型模拟应用,其中包含TempTestTableId
,Age
和Name
列。我写了这个(基于MSDN Article):
using (SqlConnection connection =
new SqlConnection("data source=localhost;initial catalog=fishsticks;integrated security=True;MultipleActiveResultSets=True;"))
{
SqlDataAdapter dataAdpater = new SqlDataAdapter(
"SELECT temptesttableid, Age, Name FROM TempTestTable",
connection);
dataAdpater.UpdateCommand = new SqlCommand(
"UPDATE TempTestTable SET Age = @Age, Name = @Name " +
"WHERE TempTestTableId = @TempTestTableId", connection);
dataAdpater.InsertCommand = new SqlCommand(
"INSERT INTO TempTestTable (Age, Name) " +
"VALUES (@Age, @Name)", connection);
SqlParameter parameter = dataAdpater.UpdateCommand.Parameters.Add(
"@TempTestTableId", SqlDbType.Int);
dataAdpater.InsertCommand.Parameters.Add(
"@Age", SqlDbType.Int, 10, "Age");
dataAdpater.InsertCommand.Parameters.Add(
"@Name", SqlDbType.NVarChar, 50, "Name");
dataAdpater.UpdateCommand.Parameters.Add(
"@Age", SqlDbType.Int, 10, "Age");
dataAdpater.UpdateCommand.Parameters.Add(
"@Name", SqlDbType.NVarChar, 50, "Name");
parameter.SourceColumn = "TempTestTableId";
parameter.SourceVersion = DataRowVersion.Original;
DataTable tempTestTable = new DataTable();
tempTestTable.Columns.Add("Age");
tempTestTable.Columns.Add("Name");
tempTestTable.Columns.Add("TempTestTableId");
var row1 = tempTestTable.NewRow();
row1["Age"] = 10;
row1["Name"] = "Smith";
row1["TempTestTableId"] = 1;
var row2 = tempTestTable.NewRow();
row2["Age"] = 40;
row2["Name"] = "Jones";
row2["TempTestTableId"] = 2;
tempTestTable.Rows.Add(row1);
tempTestTable.Rows.Add(row2);
dataAdpater.Update(tempTestTable);
数据库中已有TempTestTableId = 1
的记录,因此理论上它会更新该记录,并插入ID为2的新记录。但是,当我运行代码时,它会插入两个项目。
有什么想法吗?
答案 0 :(得分:3)
不,DataAdapter
只会查看DataRow的RowState属性。如果Added
InsertCommand
将被执行,如果它是Modified
,则UpdateCommand
将被执行。您必须先从数据库中将此行加载到表中。
您可以使用DataTable
填充空DataAdapter
,并使用SelectCommand
填充两个参数。如果表为空,则可以手动添加DataRow
,否则可以使用更新的值(如果有)修改行并调用dataAdpater.Update(tempTestTable)
。
这是一个例子(未经测试):
SqlDataAdapter dataAdpater = new SqlDataAdapter(
"SELECT temptesttableid, Age, Name FROM TempTestTable WHERE Name = @Name",
connection);
DataTable testTable = new DataTable();
// note that you should use an available csv-parser instead
foreach (string line in File.ReadAllLines(path))
{
string[] columns = line.Split(new char[]{'\t'}, StringSplitOptions.None);
if(columns.Length >= 2)
{
string name = columns[0].Trim();
string ageStr = columns[1].Trim();
int age;
if (int.TryParse(ageStr, out age))
{
dataAdpater.SelectCommand.Parameters.AddWithValue("@Name", name);
int rowsAdded = dataAdpater.Fill(testTable);
if (rowsAdded == 0)
{
testTable.Rows.Add(name, age);
}
else
{
// update values?
}
}
}
}
dataAdpater.Update(testTable);