C# 在实体框架中手动更新已修改的集合状态
我在添加或删除设置了C# 在实体框架中手动更新已修改的集合状态,c#,entity-framework,C#,Entity Framework,我在添加或删除设置了AutoDetectChangesEnabled=false的实体的关系时遇到一些问题。示例模型和代码如下所示: public class Category : Entity { public Guid CategoryId { get; set; } public virtual ICollection<UserProfile> UserProfiles { get; set; } public string N
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();
但我看不到任何类似的情况表明集合已被更改。您可以使用
context.ChangeTracker.DetectChanges()
来执行此操作,EF将检查条目是否已更改,然后标记将被分配到数据库中,因此您只需在保存更改之前更改此方法,请执行以下代码:
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();
如果不使用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);
将处理类别属性的关系修改。ChangeTracker
类不保存有关模型状态的所有数据。它只包含实体状态的数据,而不包含独立关联状态的数据,如多对多关系(如本文所述)
这些更改在ObjectStateManager
类中跟踪。您应该能够使用changelationshipstate
方法将两个实体之间的关系标记为已更改(请参阅)
旁注-要为DbContext
获取ObjectStateManager
,必须将DbContext
强制转换为ObjectContext
var objectStateManager =
((IObjectContextAdapter)dbcontext).ObjectContext.ObjectStateManager;
感谢您的输入,这看起来确实有效,但是有没有办法手动设置该状态(类似于Entry().state),这样就不需要调用DetectChanges()?它大概是在设置某些内容的状态,以便SaveChanges()知道要更新什么。再次感谢您提供的信息。@Domtar您为什么要从DetectChanges中退出?你为什么需要手动操作?@Domtar我更改了答案以适应你的问题,没有使用DetectChanges。太好了,谢谢你提供的信息。在AutoDetectChanges方面,我们正在导入大量关系,并且我们正在使用的存储库(genericunitofworkandrepositories.codeplex.com)让我们手动设置内容的状态。这么多的关系中,唯一的东西,那里没有手动设置。我想如果我已经为90%的更改设置了状态,为什么还要检查所有其他检测更改代码。谢谢您的回复。@Domtar Np,遗憾的是,这对正确答案都没有用处。
objectStateManager.ChangeRelationshipState(userProfile, category, x => x.Categories, EntityState.Added);
var objectStateManager =
((IObjectContextAdapter)dbcontext).ObjectContext.ObjectStateManager;