[英]Manually update collections modified status in Entity Framework
我在使用AutoDetectChangesEnabled = false
set從實體中添加或刪除關系時遇到了一些麻煩。 示例模型和代碼如下:
public class Category : Entity
{
public Guid CategoryId { get; set; }
public virtual ICollection<UserProfile> UserProfiles { get; set; }
public string Name { get; set; }
}
public class UserProfile : Entity
{
public Guid UserProfileId { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public string Name { get; set; }
}
var context = new OfContext();
context.Configuration.AutoDetectChangesEnabled = false;
var userProfile = context.UserProfiles
.Include(up => up.Categories)
.FirstOrDefault(up => up.UserProfileId == new Guid("XXXX"));
var category = context.Categories
.FirstOrDefault(c => c.CategoryId == new Guid("XXXX"));
userProfile.Categories.Add(category);
userProfile.Name = "Updated";
context.Entry(userProfile).State = EntityState.Modified;
context.SaveChanges();
我遇到的問題是,將類別添加到集合中並沒有保存SaveChanges
。 如果我具有AutoDetectChangesEnabled = true
,則此更改將被保留並保留。 因此,我想真正的問題是,如何手動指示此集合已被修改。
我知道對於屬性,我可以使用以下內容
.Property(u => u.Name).IsModified
但是我沒有看到任何類似的東西來表示集合已被更改。
您可以使用context.ChangeTracker.DetectChanges()
進行此操作,EF將檢查條目是否已更改,然后將標記保留在數據庫中,因此您只需在SaveChanges
之前更改此方法,請更改代碼:
public class Category : Entity
{
public Guid CategoryId { get; set; }
public virtual ICollection<UserProfile> UserProfiles { get; set; }
public string Name { get; set; }
}
public class UserProfile : Entity
{
public Guid UserProfileId { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public string Name { get; set; }
}
var context = new OfContext();
context.Configuration.AutoDetectChangesEnabled = false;
var userProfile = context.UserProfiles.Include(up => up.Categories).FirstOrDefault(up => up.UserProfileId == new Guid("XXXX"));
var category = context.Categories.FirstOrDefault(c => c.CategoryId == new Guid("XXXX"));
userProfile.Categories.Add(category);
userProfile.FirstName = "Updated";
context.Entry(userProfile).State = EntityState.Modified;
context.ChangeTracker.DetectChanges();
context.SaveChanges();
在這種情況下,您也可以刪除該行
context.Entry(userProfile).State = EntityState.Modified;
如果您不使用DetectChanges方法,則可以通過這種方式使用ObjectStateManager
var context = new OfContext();
context.Configuration.AutoDetectChangesEnabled = false;
var userProfile = context.UserProfiles.Include(up => up.Categories).FirstOrDefault(up => up.UserProfileId == new Guid("XXXX"));
var category = context.Categories.FirstOrDefault(c => c.CategoryId == new Guid("XXXX"));
userProfile.Categories.Add(category);
userProfile.FirstName = "Updated";
var objectStateManager = ((IObjectContextAdapter)context).ObjectContext.ObjectStateManager;
objectStateManager.ChangeRelationshipState(userProfile, category, x => x.Categories, EntityState.Added);
objectStateManager.ChangeObjectState(userProfile, EntityState.Modified);
context.SaveChanges();
這條線
objectStateManager.ChangeObjectState(userProfile, EntityState.Modified);
將處理FirstName屬性以及其他任何簡單屬性的修改。
而這條線
objectStateManager.ChangeRelationshipState(userProfile, category, x => x.Categories, EntityState.Added);
將處理Categories屬性的關系修改。
ChangeTracker
類不會保存有關模型狀態的所有數據。 它僅包含有關實體狀態的數據,而不包含有關獨立關聯狀態(例如,多對多關系)的數據(如本答案所述 )
這些更改在ObjectStateManager
類中進行跟蹤。 您應該能夠將兩個實體之間的關系標記為使用ChangeRelationshipState
方法進行了更改(請參見官方文檔 )
旁注 -要獲取DbContext
的ObjectStateManager
,必須將DbContext
轉換為ObjectContext
var objectStateManager =
((IObjectContextAdapter)dbcontext).ObjectContext.ObjectStateManager;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.