在Entity Framework中手动更新集合已修改状态

时间:2015-12-11 22:00:56

标签: c# entity-framework

我在设置AutoDetectChangesEnabled = false的实体中添加或删除关系时遇到问题。示例模型和代码如下:

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

但是我没有看到类似的东西表明收藏品已被更改。

2 个答案:

答案 0 :(得分:1)

您可以使用 context.ChangeTracker.DetectChanges()来执行此操作,EF将检查条目是否已更改,然后标记将保留在数据库中,因此您只需更改此方法 SaveChanges ,代码:

&#xA;&#xA;
 公共类别:实体&#xA; {&#xA; public Guid CategoryId {get;组; &#xA; public virtual ICollection&lt; UserProfile&gt; UserProfiles {get;组; &#xA; public string Name {get;组; }&#xA;}&#xA;&#xA; public class UserProfile:Entity&#xA; {&#xA; public Guid UserProfileId {get;组; }&#XA;&#XA;公共虚拟ICollection&lt;类别&gt;类别{get;组; }&#XA; public string Name {get;组; }&#xA;}&#xA;&#xA; var context = new OfContext();&#xA; context.Configuration.AutoDetectChangesEnabled = false;&#xA; var userProfile = context.UserProfiles.Include(up =&gt; ; up.Categories).FirstOrDefault(up =&gt; up.UserProfileId == new Guid(“XXXX”));&#xA; var category = context.Categories.FirstOrDefault(c =&gt; c.CategoryId == new Guid (“XXXX”));&#xA; userProfile.Categories.Add(category);&#xA; userProfile.FirstName =“Updated”;&#xA; context.Entry(userProfile).State = EntityState.Modified;& #xA; context.ChangeTracker.DetectChanges();&#xA; context.SaveChanges();&#xA;  
&#xA;&#xA;

在这种情况下,你可以也删除该行

&#xA;&#xA;
  context.Entry(userProfile).State = EntityState.Modified;&#xA;  
&#xA ;&#xA;

如果你不使用DetectChanges方法,你可以用这种方式使用ObjectStateManager

&#xA;&#xA;
  var context = new OfContext();&# xA; context.Configuration.AutoDetectChangesEnabled = false;&#xA; var userProfile = context.UserProfiles.Include(up =&gt; up .Categories).FirstOrDefault(up =&gt; up.UserProfileId == new Guid(“XXXX”));&#xA; var category = context.Categories.FirstOrDefault(c =&gt; c.CategoryId == new Guid(“XXXX”));&#xA; userProfile .Categories.Add(category);&#xA; userProfile.FirstName =“Updated”;&#xA; var objectStateManager =((IObjectContextAdapter)context).ObjectContext.ObjectStateManager;&#xA; objectStateManager.ChangeRelationshipState(userProfile,category, x =&gt; x.Categories,EntityState.Added);&#xA; objectStateManager.ChangeObjectState(userProfile,EntityState.Modified);&#xA; context.SaveChanges(); &#xA;  
&#xA;&#xA;

此行

&#xA;&#xA;

objectStateManager.ChangeObjectState(userProfile,EntityState .Modified);

&#xA;&#xA;

将处理FirstName属性和任何其他简单属性的修改。

&#xA;&#xA; < p>这一行

&#xA;&#xA;
  objectStateManager.ChangeRelationshipState(userProfile,category,x =&gt; x.Categories,EntityState.Added);&#xA;  
&#xA;&#xA;

将处理Categories属性的关系修改。

&#xA;

答案 1 :(得分:0)

ChangeTracker类不包含有关模型状态的所有数据。它仅包含有关实体状态的数据,但不包含独立关联的状态,例如多对多关系(如answer中所述)

ObjectStateManager课程中跟踪这些更改。您应该能够使用ChangeRelationshipState方法标记两个实体之间的关系(请参阅official documentation

旁注 - 要获得ObjectStateManager的{​​{1}},必须将DbContext投放到DbContext

ObjectContext