テーブルemployee
があり、それらの場所を新しい場所に更新する必要があるため、一括更新が必要です。 DapperO.R.Mを使用してそうするのを手伝ってください。
私の主キーはEmployee-id
。
以下に、一度に1つのレコードで更新されるサンプルコードを示します。
// 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();
}
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 Employee{Age = 1, Name = "foo", Id = 1},
new Employee{Age = 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 は友達が書いたものです。挿入ステートメントのグループを生成し、それらを一度に実行するだけです。