Dapper for NET Core:插入表并返回插入行的 id

Posted

技术标签:

【中文标题】Dapper for NET Core:插入表并返回插入行的 id【英文标题】:Dapper for NET Core: Insert into a table and return id of inserted row 【发布时间】: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,但其他的还是一样的。 【参考方案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;
        
    

【讨论】:

以上是关于Dapper for NET Core:插入表并返回插入行的 id的主要内容,如果未能解决你的问题,请参考以下文章

Dapper in .Net Core

.Net Core中Dapper的使用详解

ASP.NET Core 中的 ORM 之 Dapper

.net core 3.1 加入ORM框架(Dapper)

.net core系列之《.net core中使用MySql以及Dapper》

.NET Core开发日志——Dapper与MySQL