所以我是新來EF(我使用EF6),我有問題了解這個概念,我試圖更新實體與子集合。關於跟蹤EF(更新實體與子集合)
這裏是我的實體類:
public class TimeSheet
{
public int TimeSheetID { get; set; }
public virtual ICollection<TimeSheetDetail> Details { get; set; }
}
public class TimeSheetDetail
{
public int TimeSheetDetailID { get; set; }
public int TimeSheetID { get; set; }
public virtual TimeSheet TimeSheet { get; set; }
}
我的更新方法:
public void Update(TimeSheet obj)
{
var objFromDB = Get(obj.TimeSheetID);
var deletedDetails = objFromDB.Details.Except(obj.Details).ToList();
_dbContext.Entry(obj).State = EntityState.Modified;
//track if details exist
foreach (var details in obj.Details)
{
_dbContext.Entry(details).State = details.TimeSheetDetailID == 0 ? EntityState.Added : EntityState.Modified;
}
//track deleted item
foreach (var deleted in deletedDetails)
{
_dbContext.Entry(deleted).State = EntityState.Deleted;
}
}
public TimeSheet Get(object id)
{
//return _timeSheet.Find(id); //Without AsNoTracking I got error
int x = Convert.ToInt32(id);
return _timeSheet.AsNoTracking().SingleOrDefault(a => a.TimeSheetID == x);
}
上面的代碼給我Attaching an entity of type 'ClassName' failed because another entity of the same type already has the same primary key value
。所以我的問題是:
如何更新與EF的子集合?意思是我需要在數據庫中不存在的情況下添加新數據,否則進行更新,或者如果數據庫在
POST
中刪除,則從數據庫中刪除。如果我不使用
AsNoTracking()
,它會拋出Saving or accepting changes failed because more than one entity of type 'ClassName' have the same primary key value
。我注意到,如果我沒有使用AsNoTracking()
,我的DbSet
將數據從DB添加到它的Local
屬性,導致EF框架拋出錯誤,因爲它認爲我有重複的數據,導致錯誤是由我的DbSet
造成的。這實際上是如何工作的?正如你可以看到我試圖比較
objFromDb
與obj
來檢查用戶是否刪除其中的一個細節,以便我可以從數據庫中刪除它。相反,我從收集結果中得到了一堆DynamicProxies
。什麼是DynamicProxies
,它是如何工作的?EF上有沒有好的文章或101教程?到目前爲止,我只看到一個簡單的,不能幫助我的情況,我四處張望,找到一個混合的答案如何做的東西。說實話,在這一點上,我希望我會用經典的ADO.Net而不是EF。
對於答覆號2,如果EF能自動跟蹤內部的變化實體,爲什麼它不能檢測到子集合中的更改?例如,如果我在我的Update方法中使用這些代碼_timeSheet.Attach(obj); _dbContext.Entry(obj).State = EntityState.Modified;',它不會識別集合屬性中的更改。 – warheat1990
實體框架無法跟蹤導航屬性內的更改。導航屬性可以通過延遲加載進行加載,也可以爲空,如果您使用空集合更新實體,則實體框架不知道該做什麼。 – JoeJoe87577