我的问题很常见,但我没有找到任何解决方案。这是我的代码:
public async Task<QueryResult> RollbackQuery(ActionLog action)
{
var inputParameters = JsonConvert.DeserializeObject<Parameter[]>(action.Values);
var data = DeserailizeByteArrayToDataSet(action.RollBackData);
using (var structure = PrepareStructure(action.Query, action.Query.DataBase, inputParameters))
{
//_queryPlanner is the implementor for my interface
return await _queryPlanner.RollbackQuery(structure, data);
}
}
我需要加载 DataTable(从任何地方)并将数据替换到数据库。这是我的回滚功能。这个函数使用一个“CommandStructure”,我已经封装了所有的 SqlClient 对象。PrepareStructure 初始化所有对象
//_dataLayer is an Helper for create System.Data.SqlClient objects
//ex: _dataLayer.CreateCommand(preSelect) => new SqlCommand(preSelect)
private CommandStructure PrepareStructure(string sql, string preSelect, DataBase db, IEnumerable<Parameter> inputParameters)
{
var parameters = inputParameters as IList<Parameter> ?? inputParameters.ToList();
var structure = new CommandStructure(_logger);
structure.Connection = _dataLayer.ConnectToDatabase(db);
structure.SqlCommand = _dataLayer.CreateCommand(sql);
structure.PreSelectCommand = _dataLayer.CreateCommand(preSelect);
structure.QueryParameters = _dataLayer.CreateParemeters(parameters);
structure.WhereParameters = _dataLayer.CreateParemeters(parameters.Where(p => p.IsWhereClause.HasValue && p.IsWhereClause.Value));
structure.CommandBuilder = _dataLayer.CreateCommandBuilder();
structure.DataAdapter = new SqlDataAdapter();
return structure;
}
因此,我的函数使用 SqlCommandBuilder 和 DataAdapter 对数据库进行操作。PreSelectCommand 类似于“Select * from Purchase where CustomerId = @id”表 Purchase 在 ID 字段上有一个 primaryKey
public virtual async Task<QueryResult> RollbackQuery(CommandStructure cmd, DataTable oldData)
{
await cmd.OpenConnectionAsync();
int record = 0;
using (var cmdPre = cmd.PreSelectCommand as SqlCommand)
using (var dataAdapt = new SqlDataAdapter(cmdPre))
using (var cmdBuilder = new SqlCommandBuilder(dataAdapt))
{
dataAdapt.UpdateCommand = cmdBuilder.GetUpdateCommand();
dataAdapt.DeleteCommand = cmdBuilder.GetDeleteCommand();
dataAdapt.InsertCommand = cmdBuilder.GetInsertCommand();
using (var tbl = new DataTable(oldData.TableName))
{
dataAdapt.Fill(tbl);
dataAdapt.FillSchema(tbl, SchemaType.Source);
tbl.Merge(oldData);
foreach (DataRow row in tbl.Rows)
{
row.SetModified();
}
record = dataAdapt.Update(tbl);
}
}
return new QueryResult
{
RecordAffected = record
};
}
我执行代码,我没有任何错误,但数据没有更新。变量“记录”包含正确数量的修改(??)记录,但......在桌子上什么都没有
有人能帮我吗?
编辑 1: 使用 SQL Profiler,我看到在 DB 上没有执行任何查询。仅在 .Fill(tbl) 命令上选择查询。
编辑2: 现在我做了一个改变:
tbl.Merge(oldData) => tbl.Merge(oldData, true)
所以我看到执行了预期的查询,但是使用了相反的参数。
UPDATE Purchase SET price=123 where id=6 and price=22
代替
UPDATE Purchase SET price=22 where id=6 and price=123