.NET
Entity Framework ORM
雖說自己在先前的文章:
曾提到用不同的DbContext來操作Entity的小陷阱。
結果一年後的今天還是踩到了這個雷 ~_~|| (而且完全沒有Exception message …)
▋Reproduce the problem
在以下程式碼中,當Entity需要傳到不同的方法操作時,如果是不同的DbContext,會造成實際上已更新物件,但資料庫卻未更新的情況。
//In Method 1
using (var daoService = new BloodTypeService<BloodType>(new TmsDbContext()))
{
bloodType = daoService.GetAll().ToList().ElementAt(0);
LogUtility.Logger.Debug(bloodType.Name);
}
//In Method 2
using (var daoService = new BloodTypeService<BloodType>(new TmsDbContext()))
{
bloodType.Name = "AAA";
daoService.Update(bloodType); //包含SaveChanges()
var bloodTypeReQuery =
daoService.GetAll().ToList().ElementAt(0);
LogUtility.Logger.Debug(bloodTypeReQuery.Name);
}
|
上面的執行結果是
A
A
也就是“沒有更新到實體資料庫”,
▋Refinement 1
var dbContext = new TmsDbContext();
//In Method 1
using (var daoService = new BloodTypeService<BloodType>(dbContext))
{
bloodType =
daoService.GetAll().ToList().ElementAt(0);
LogUtility.Logger.Debug(bloodType.Name);
}
//In Method 2
using (var daoService = new BloodTypeService<BloodType>(dbContext))
{
bloodType.Name = "AAA";
daoService.Update(bloodType); //包含SaveChanges()
var bloodTypeReQuery =
daoService.GetAll().ToList().ElementAt(0);
LogUtility.Logger.Debug(bloodTypeReQuery.Name);
}
|
上面的兩個方法共用同一個DbContext後,就可以成功更新該筆資料庫的資料。
Output結果為
A
AAA
▋Refinement 2
也可以使用Detach & attach的方式來修正程式碼。
BloodType bloodType = null;
//In Method 1
var dbContext1 = new TmsDbContext();
using (var daoService = new BloodTypeService<BloodType>(dbContext1))
{
bloodType = daoService.GetAll().ToList().ElementAt(0);
//Detach method 1 : Using
ObjectContext
ObjectContext objContext1 = ((IObjectContextAdapter)dbContext1).ObjectContext;
objContext1.Detach(bloodType);
//Detach method 2 : Using EntityState to detach
//dbContext1.Entry(bloodType).State
= EntityState.Detached;
LogUtility.Logger.Debug(bloodType.Name);
}
//In Method 2
var dbContext2 = new TmsDbContext();
using (var daoService = new BloodTypeService<BloodType>(dbContext2))
{
//Attach method 1 : Using
DbSet.Attach()
dbContext2.Set(typeof(BloodType)).Attach(bloodType);
//Attach method 2 : Using
EntityState to attach (If the DAO is modified before attaching it, must use this way)
//dbContext2.Entry(bloodType).State
= EntityState.Modified;
bloodType.Name = "AAA";
daoService.Update(bloodType);
//包含SaveChanges()
var bloodTypeReQuery =
daoService.GetAll().ToList().ElementAt(0);
LogUtility.Logger.Debug(bloodTypeReQuery.Name);
}
|
沒有留言:
張貼留言