【问题标题】:.NET SqlConnection and SqlCommand.NET SqlConnection 和 SqlCommand
【发布时间】:2011-05-04 08:04:08
【问题描述】:

我在 Dapper ORM 的项目中使用 SqlConnection 和 SqlCommand 类,但我遇到了一个奇怪的问题。当我使用 SqlCommand 在 db 表中插入一行时,它总是可以正常工作,当我选择更新的数据表单表时,一切都很好,但是在关闭应用程序后,我所做的更改并没有提交,就像数据已保存在某个缓存中一样。 例如,我创建了一个只有两列(UserId (PK) 和 UserName (Unique))的简单表,即使在这种情况下也不会保存更改。 我正在使用以下代码插入一行:

using (SqlConnection c = new SqlConnection(Settings.Default.UsersConnectionString))
        {
            c.Open();


            using (SqlCommand d = new SqlCommand())
            {
                d.CommandText = "INSERT INTO Users (UserName) VALUES ('SomeName')";
                d.CommandType = System.Data.CommandType.Text;
                d.Connection = c;
                int t = d.ExecuteNonQuery();
            }


            c.Close();
        }

【问题讨论】:

  • 旁白:c.Close(); row 是多余的,这将由外部 using 子句处理。

标签: .net sql sqlconnection sqlcommand dapper


【解决方案1】:

您很可能处于未提交的事务中。也许 Dapper ORM 已经启动了一个事务,您必须告诉它提交所有更改。

【讨论】:

  • 为了清楚起见,我制作了一个简单的控制台应用程序,只有上面唯一的代码,但仍然存在同样的问题。
【解决方案2】:

据推测,您的服务器的默认设置已设置为 implicit transactions 已打开。这意味着,如果您执行一个命令并且当前没有打开事务,SQL Server 将自动启动一个事务(一如既往)。但是当命令成功完成时,该事务保持打开状态,需要发出显式提交。

要确定是否是这种情况,请尝试查询@@OPTIONS

IF @@OPTIONS & 2 > 0 
RAISERROR ('Implicit transactions are turned on', 1, 1)

【讨论】:

    【解决方案3】:

    dapper 中的这段代码应该是:

    var name = "SomeName";
    int t  = c.Execute("INSERT INTO Users (UserName) VALUES (@name)", new {name});
    

    Dapper 没有内部事务管理,它必须使用可选的事务参数传入。

    我的直觉告诉我你正在连接到不同的数据库来插入数据。 Damiens 的隐式交易的东西,很容易验证。

    【讨论】:

    • 任何方式使用 Dapper 来获取最后插入的 ID?
    • c.Query<Decimal>("insert ... select SCOPE_IDENTITY()").First() .. 不确定 numeric(38) 是否干净地映射到 int @Developr
    • 我在 SQL 中的身份列是 int。无论我将 Dapper 查询设置为什么(int、long 等),它都会给我一个“指定的强制转换无效”。 Dapper 线上的异常:1104 return (T)val;有没有办法执行它,我将它作为输出参数取回,类似于存储过程示例的工作方式?不确定这是否更清洁,但至少可以替代。
    • 顺便说一句,无效的转换是因为它将返回的 SQL 整数视为十进制!现在,我更改了 c.Query 并且它正在工作,尽管它有点杂乱无章。
    • 是的,它是十进制的...... Dapper 是设置正确类型的坚持者......它不会通过设计向下转换或向上转换
    【解决方案4】:

    可能是数据库自动创建了一个未提交的事务,尝试在代码中创建自己的事务并手动提交,看看是否有效

    using (SqlConnection c = new SqlConnection(Settings.Default.UsersConnectionString))
    {
       c.Open();
       using (SqlTransaction t = c.BeginTransaction("InsertIntoUsers"))
       {
            using (SqlCommand d = new SqlCommand())
            {
                d.CommandText = "INSERT INTO Users (UserName) VALUES ('SomeName')";
                d.CommandType = System.Data.CommandType.Text;
                d.Connection = c;
                int t = d.ExecuteNonQuery();
            }
            t.Commit();
       }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-06
      • 2018-03-27
      • 2011-03-23
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 1970-01-01
      相关资源
      最近更新 更多