任何人都可以帮助使用 Dapper ORM 进行批量更新吗?

Posted

技术标签:

【中文标题】任何人都可以帮助使用 Dapper ORM 进行批量更新吗?【英文标题】:Can anybody help to do bulk update using Dapper ORM? 【发布时间】:2016-02-01 15:16:20 【问题描述】:

我有一张桌子employee,我必须将他们的位置更新到新位置,所以我需要批量更新。请使用 Dapper O.R.M. 帮助我这样做

我的主键是Employee-id

您可以在下面看到一次更新单个记录的示例代码。

// Employees is list of class class Employee
SqlConnection connection = new SqlConnection(connectionstring);
connection.open();

foreach (Employee employee in Employees)

    string query = @"UPDATE [dbo].[Employee]    
                     SET Name = @Name, Age = @Age, Sex = @Sex, 
                         Location = @Location  
                     WHERE Id = @Id";

    connection.QueryAsync<bool>(query, new  @Id = employee.Id, @Name = employee.Name, 
                                             @Sex = employee.sex, @Age = employee.age, 
                                             @Location = employee.location)).SingleOrDefault();
   

【问题讨论】:

我希望您正在等待致电connection.QueryAsync&lt;bool&gt;。如果你不在异步方法中,你应该调用connection.Query&lt;bool&gt; 类似问题:***.com/questions/32635347/… 【参考方案1】:

Dapper 支持从列表插入/更新。

internal class Employee

    public int Id  get; set; 
    public int Age  get; set; 
    public string Name  get; set; 


[TestFixture]
public class DapperTests

    private IDbConnection _connection;

    [SetUp]
    public void SetUp()
    
        _connection = new SqlConnection(@"Data Source=.\sqlexpress; Integrated Security=true; Initial Catalog=mydb");
        _connection.Open();

        _connection.Execute("create table employees(Id int, Name varchar(100), Age int)");
        _connection.Execute("insert into employees(Id, Name) values(1, 'xxx'), (2, 'yyy')");
    

    [TearDown]
    public void TearDown()
    
        _connection.Execute("drop table employees");
        _connection.Close();
    

    [Test]
    public void BulkUpdateFromAListTest()
    
        _connection.Execute(@"update employees set Name = @Name where Id = @Id",
            new List<Employee> 
            
                new EmployeeAge = 1, Name = "foo", Id = 1,
                new EmployeeAge = 2, Name = "bar", Id = 2
            );

        var result = _connection.Query<Employee>("select * from employees").ToList();

        Assert.That(result.Count, Is.EqualTo(2));
        Assert.That(result.FirstOrDefault(x => x.Id == 1).Name == "foo");
        Assert.That(result.FirstOrDefault(x => x.Id == 2).Name == "bar");

    

Dapper 的问题在于它单独执行每个命令,所以如果你有很多,就会出现性能问题。

另一种方法是创建一个临时表,然后使用连接进行更新。为此,您可以执行以下操作:

[TestFixture]
public class BatchRunnerTests

    private readonly IDbConnection _dbConnection;

    public BatchRunnerTests()
    
        _dbConnection = new SqlConnection(@"Data Source=.\sqlexpress; Integrated Security=true; Initial Catalog=Bktb4_CaseMgr_Db"); ;
        _dbConnection.Open();
    

    [Test]
    public void TestBatchRunner()
    
        var records = new List<Employee>
        
            new Employee Age = 1, Name = "foo", Id = 1,
            new Employee Age = 2, Name = "bar", Id = 2
        ;

        var tablwToUpdateFrom = BuildTable(records);

        _dbConnection.Execute("update a set Name = b.Name from employees a join " + tablwToUpdateFrom + " b on a.Id = b.Id");
    

    public string BuildTable(List<Employee> data)
    
        var tableName = "#" + Guid.NewGuid();

        _dbConnection.Execute("create table [" + tableName + "] ( Id int null, Name varchar(50) null)");

        var batchRunner = new SqlBatchRunner(_dbConnection);

        data.ToList().ForEach(x =>
            batchRunner.RecordingConnection.Execute(@"insert into [" + tableName + "] values(@Id, @Name)", x));

        batchRunner.Run();
        return tableName;
    

我在这里使用的library 是一个朋友写的。它只会生成一组插入语句并立即执行。

【讨论】:

嗨罗伊感谢您的回复。我正在尝试使用您提供的使用临时表的代码。但不幸的是,我找不到 SqlBatchRunner 类。你能帮我找出相同的课程吗?到那时我会尝试使用你上面提到的第一种方法 嘿,这个类是库的一部分:github.com/kennethchoe/SqlBatchProcess 支持 N 条更新语句Execute("update 1; update 2; ...; update n")? 注意:SQL Server 不接受表名中的字符-。正确的名称应该类似于 var tableName = $"#Guid.NewGuid().ToString().Replace("-", "")"; 是的,如果 dapper 只是执行 n 次插入,为什么不直接生成 SQL,然后将整个语句交给数据库? Shame Dapper 不够聪明,无法仅在 1 个 SQL 命令中执行此操作,可能超出其范围?

以上是关于任何人都可以帮助使用 Dapper ORM 进行批量更新吗?的主要内容,如果未能解决你的问题,请参考以下文章

.NET轻量级ORM组件Dapper修炼手册

.NET轻量级ORM组件Dapper修炼手册

.net平台性能很不错的轻型ORM类Dapper

ORM 轻量级框架 Dapper(介绍)

ORM 轻量级框架 Dapper(介绍)

轻量级高性能ORM框架:Dapper高级玩法