Misalkan kita mempunyai dua tabel (Entity1 & Entity2) dengan struktur seperti di bawah ini:

ParentId reference ke Id di tabel yang sama
Tujuannya adalah menduplikasi row ke tabel lain berdasarkan CategoryId.
Kendalanya, Id dan ParentId antara kedua tabel tidak sama, sehingga copy rows dengan method berikut.
List<Entity1> entities1 = await RepoEntity1.FindAllByCategoryId(categoryId);
if (entities1.Any())
{
// Kamus
List<Entity2> entities2 = new List<Entity2>();
List<Tuple<int?, int?>> tupleIds = new List<Tuple<int?, int?>>();
Tuple<int?, int?> tupleId;
// Algo
foreach (Entity1 entity1 in entities1)
{
Entity2FormStub modelEntity2 = new Entity2FormStub(entity1); // Copy model
Entity2 entity2 = new Entity2();
modelEntity2.MapDbObject(entity2);
entities2.Add(entity2);
}
await RepoEntity2.SaveAllAsync(entities2); // First save without Parent ID on Entity2
// Add some tuples
using (var e1 = entities1.GetEnumerator())
using (var e2 = entities2.GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext())
{
var item1 = e1.Current;
var item2 = e2.Current;
tupleId = new Tuple<int?, int?>(item1.Id, item2.Id);
tupleIds.Add(tupleId);
}
}
// Edit all Entity 2 Parent ID
using (var e1 = entities1.GetEnumerator())
using (var e2 = entities2.GetEnumerator())
{
while (e1.MoveNext() && e2.MoveNext())
{
Entity2 entity2Edit = new Entity2();
var item1 = e1.Current;
var item2 = e2.Current;
if (item1.ParentId != null)
{
entity2Edit = await RepoEntity2.FindByPrimaryKeyAsync(item2.Id);
entity2Edit.ParentId = tupleIds.Where(x => x.Item1 == item1.ParentId).FirstOrDefault().Item2; // Use tuple for reference
RepoEntity2.Save(entity2Edit);
}
}
}
}
Code edit parent id entity2 (setelah // Edit all Entity 2 Parent ID) kurang bagus secara performa. Lebih baik dibuat dengan flow berikut:
1. Mengambil seluluruh data yang ada diedit ke dalam object EF. Pada contoh diatas object tersebut sudah ada di entities2 CMIIW.
2. Edit field yang diperlukan.
3. Save data secara batch ke database.