【问题标题】:Dapper for NET Core: Insert into a table and return id of inserted rowDapper for NET Core:插入表并返回插入行的 id
【发布时间】:2018-06-01 21:05:36
【问题描述】:

我的存储库中有以下方法。到目前为止,我相信返回的 int 只是表明操作是否成功的一个值。我希望 int 是成功执行后要返回的 id (这是表的单列)。我如何做到这一点?

    public async Task<int> AddNewGroup()
    {
        using(_connection)
        {
            _connection.Open();
            var id = await _connection.ExecuteAsync("INSERT INTO groups").Single();
        }
    }

【问题讨论】:

  • This 是关于 MS Access,但其他的还是一样的。

标签: asp.net-core dapper


【解决方案1】:

您可以运行包含 2 个部分的查询,第一个是 INSERT 部分,第二个是 SELECT 部分。在 SELECT 部分,您可以返回(选择)您想要的任何列值。

例如,如果您的组表有一个名为GroupId 的主键列,并且您已将该列设置为标识值生成(自动值生成),则可以调用SCOPE_IDENTITY() 来获取生成的值。

我们将使用QueryAsync 方法。

public async Task<int> AddNewGroup()
{
   using(_connection)
   {
      _connection.Open();
      var q = @"INSERT INTO Groups(Name,Description) VALUES
                 (@name, @desc); SELECT CAST(SCOPE_IDENTITY() as int)"
      var result = await _connection.QueryAsync<int>(q, 
                                          new { @name="some name", @desc="some desc"});
      return result.Single();
   }
}

【讨论】:

    【解决方案2】:

    您不必手动创建插入查询,您可以使用 Dapper.Contrib github 来帮助您管理 CRUD 操作。

    使用 Dapper.Contrib 您可以执行以下操作:

     public async Task<int> AddNewGroup(Group entity)
     {
            using (_connection)
            {
                 _connection.Open();
                 var id = await _connection.InsertAsync(entity);
             }
     }
    

    【讨论】:

    • 当标识列是 GUID 而不是自增 int 时,您知道解决方案吗?
    • Dapper.Contrib 似乎只有返回 int 或 long 的 Insert 方法,但如果您想获取 Guid 作为插入结果,您可以使用 _connection.QueryFirstAsync 创建自己的 Insert 方法(rawSql) 其中 rawSql 是带有输出的插入语句。例如。 rawSql =“插入用户(id,用户名,名字,姓氏)OUTPUT Inserted.Id值(newid(),'rajiv','raj','iv');” .您还可以使用 OUTPUT 获取整个插入的行。
    • 嗨@Rajiv,为什么不在你的代码函数中生成guid并将其与其余部分一起发布并保存“往返”?在这种情况下,全球唯一的 guid 是理想的
    【解决方案3】:
        public static void Main()
        {
            string sql = @"INSERT INTO Customers (CustomerName, ContactName, Address, City, PostalCode, Country) 
            Values (@CustomerName, @ContactName, @Address, @City, @PostalCode, @Country);
            SELECT CustomerID FROM Customers WHERE CustomerID = SCOPE_IDENTITY();";
    
            using (var connection = new SqlConnection(GetConnectionString()))
            {
                Customer c = new Customer("Brian Adams", "Brian", "12 Jones Place", "New York", "NY12", "CA");
                                
                var id = connection.QueryFirstOrDefault<int>(sql, c);
                
                Console.WriteLine("The Customer ID is " + id);
                sql = "Select * FROM CUSTOMERS WHERE CustomerID = @ID";
                
                var rc = connection.QueryFirstOrDefault<Customer>(sql, new{ @ID = id });
            }
        }
    }
    

    【讨论】:

    • 纯代码答案是低质量的答案。
    【解决方案4】:

    如果您使用的是 SQL Azure / SQL Server,则需要使用类似的方法从查询中返回插入的值

    INSERT INTO groups OUTPUT inserted.id VALUES (...)
    

    然后使用ExecuteAsync 使用ExecuteScalarAsync

    此处引用 OUTPUT 子句: https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql?view=sql-server-2017

    【讨论】:

      【解决方案5】:

      我采取的“正确”方式是(显示使用 Guid Id 返回的存储库方法):

      public async Task<Guid> CreateClient(ClientEntity clientModel)
          {
              const string sql = @"
              INSERT INTO dbo.Clients
                  (
                      ClientCode,
                      Name,
                      IsActive
                  )
              OUTPUT Inserted.ClientId
              VALUES
                  (
                      @ClientCode,
                      @Name,
                      @IsActive
                  )";
      
              using var dbConnection = await _databaseProvider.GetConnection();
      
              var result = await dbConnection.ExecuteScalarAsync(sql, new
              {
                  ClientCode = clientModel.Code,
                  Name = clientModel.Name,
                  IsActive = clientModel.IsActive
              });
      
              if (result != null)
              {
                  return Guid.Parse(result.ToString());
              }
              else {
                  return Guid.Empty;
              }
          }
      

      【讨论】:

        猜你喜欢
        • 2012-01-06
        • 2022-11-25
        • 1970-01-01
        • 2013-08-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多