我有一个类似的存储库:
public class Repository<T> : IRepository<T> where T : class
{
private readonly IRepositoryContext _repositoryContext;
public Repository(IRepositoryContext repositoryContext)
{
_repositoryContext = repositoryContext;
_objectSet = repositoryContext.GetObjectSet<T>();
}
public virtual void Update(T entity)
{
ObjectSet.AddObject(entity);
_repositoryContext.ObjectContext.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified);
_repositoryContext.SaveChanges();
}
}
现在,它实际上适用于实体的所有标量属性,但与实体typeOf(T)
的属性关联的所有其他实体都不关心实体状态是否被修改,而EF只是添加新数据。
所以,如果您执行Repository<Student>.Update()
,并且您只更改了名称,它将找到合适的学生并更改他的名字,但它也会更改校园,尽管您已经有一个与之关联的校园那个学生,将使用不同的CampusId重新创建。
请告诉我在这种情况下更新的正确方法。
答案 0 :(得分:4)
当我想要遵循通用方法时,我所做的就是翻译成你的代码:
public class Repository<T> : IRepository<T> where T : class
{
...
public virtual void Update(T entity)
{
if (context.ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Detached)
{
throw new InvalidOperationException(...);
}
_repositoryContext.SaveChanges();
}
}
然后我的所有代码都像:
var attachedEntity = repository.Find(someId);
// Merge all changes into attached entity here
repository.Update(attachedEntity);
=&GT;以通用方式执行此操作会将大量逻辑移动到您的上层。没有更好的方法来保存大的分离对象图(特别是当涉及到多对多关系并且涉及删除关系时)。