簡體   English   中英

在Entity Framework中手動更新集合的已修改狀態

[英]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方法進行了更改(請參見官方文檔

旁注 -要獲取DbContextObjectStateManager ,必須將DbContext轉換為ObjectContext

var objectStateManager = 
    ((IObjectContextAdapter)dbcontext).ObjectContext.ObjectStateManager;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM