SqlDataAdapter.update() 不更新数据库

Posted

技术标签:

【中文标题】SqlDataAdapter.update() 不更新数据库【英文标题】:SqlDataAdapter.update() not updating database 【发布时间】:2015-04-07 04:22:47 【问题描述】:

我正在使用SqlDataAdapter 在 PostLikes 表中搜索 (PostId,UserId),如果找到该行,我正在使用SqlCommandBuilder.GetDeleteCommand() 生成删除指令并删除底层行,如果未找到该行,然后我使用SqlCommandBuilder.GetInsertCommand() 生成插入命令并使用SqlDataAdapter.Update() 将行插入到表中。但是该行没有插入到数据库中的表中。这是我到目前为止所做的事情

SqlConnection con = new SqlConnection(connectionStrings);
SqlDataAdapter sqlDataAdapter=new SqlDataAdapter("select * from PostLikes where PostId like "
                                                 +postlike.PostId+" and UserId like "
                                                 +postlike.UserId,con);
DataSet ds = new DataSet();
sqlDataAdapter.Fill(ds, "Result");
con.Open();
SqlCommandBuilder sqlCommandBuilder = new SqlCommandBuilder(sqlDataAdapter);
if(ds.Tables["Result"].Rows.Count==1)

    sqlDataAdapter.DeleteCommand = sqlCommandBuilder.GetDeleteCommand(true);
    msg = "Data is deleted";

else

    sqlDataAdapter.InsertCommand = sqlCommandBuilder.GetInsertCommand(true);
    msg = "Data is inserted";

sqlDataAdapter.Update(ds, "Result");

和表PostLikes(LikeId,PostId,UserId)

【问题讨论】:

【参考方案1】:

有几个问题:

您希望重复使用相同的命令来检测该行是否存在,并为SqlCommandBuilder 提供给SqlAdapter。 您应该对初始选择查询进行参数化,以防止 SqlInjection 攻击(并且有一点性能优势)。 CommandBuilder 将自动参数化 Insert / Delete 命令 使用SqlCommandBuilder 创建插入/删除命令后,您需要更改基础数据集,以便在Update 期间对表进行任何更改。 请注意,许多 Sql 对象是 IDisposable,应尽快处理 - using 作用域在此处提供帮助。

.

var postId = 1;
var userId = 1;
string msg;
using (var con = new SqlConnection(@"data source=..."))
using (var selectCommand = new SqlCommand(
 "select LikeId, PostId, UserId from PostLikes WHERE PostId=@PostId AND UserId=@UserId", con))
using (var sqlDataAdapter = new SqlDataAdapter(selectCommand))
using (var ds = new DataSet())

    con.Open();
    selectCommand.Parameters.AddWithValue("@PostId", postId);
    selectCommand.Parameters.AddWithValue("@UserId", userId);
    sqlDataAdapter.Fill(ds, "Result");
    using (var sqlCommandBuilder = new SqlCommandBuilder(sqlDataAdapter))
    
        if (ds.Tables["Result"].Rows.Count == 1)
        
            sqlDataAdapter.DeleteCommand = sqlCommandBuilder.GetDeleteCommand(true);
            ds.Tables["Result"].Rows[0].Delete();
            msg = "Data will be deleted";
        
        else
        
            sqlDataAdapter.InsertCommand = sqlCommandBuilder.GetInsertCommand(true);
            // Null because LikeId is Identity and will be auto inserted
            ds.Tables["Result"].Rows.Add(null, postId, userId);
            msg = "Data will be inserted";
        
        sqlDataAdapter.Update(ds, "Result");
    

我假设了以下架构:

CREATE TABLE PostLikes
(
    LikeId INT IDENTITY(1,1) PRIMARY KEY,
    PostId INT,
    UserId INT
)

我假设您想使用postId, userid 组合“切换”插入或删除行。

【讨论】:

是否 con.Open() 对 SqlDataAdapter 是必需的? 好点 - 不,它可以detect the closed connection and open it automatically。但显然,如果您还只使用基本/直接SqlCommand,则需要手动打开连接

以上是关于SqlDataAdapter.update() 不更新数据库的主要内容,如果未能解决你的问题,请参考以下文章

当 RowState = Modified 时 SQLDataAdapter.Update() 不更新

SqlDataAdapter.Update(dataset) 方法插入新行但不更新现有行

使用带参数的 SqlDataAdapter.Update()

C# SqlDataAdapter.Update()

在 SqlDataAdapter.Update() 中获取错误消息

200万条记录的SqlDataAdapter.Update()速度极慢