我的Generic Repository的这两种方法都有问题。在我的控制器中,我使用我的工作单元(调用基于通用存储库的存储库)检索当前用户。
CurrentUser = UtilisateurBuilder.Build(UnitOfWork.UsersRepository.Recuperer(user=>user.MailAddress==WebSecurity.CurrentUserName).First());
上面的代码在我的控制器的构造函数中执行,所以我总是可以访问当前的用户信息。在我的一个动作中,我有一个执行一些更新的代码:
CurrentUser.Photo = NewPathToPhoto;
UnitOfWork.UsersRepository.Update(CurrentUser);
但此时我收到以下错误:
附加“DAL.User”类型的实体失败,因为同一类型的另一个实体已具有相同的主键值。如果图中的任何实体具有冲突的键值,则在使用“附加”方法或将实体的状态设置为“未更改”或“已修改”时,可能会发生这种情况。这可能是因为某些实体是新的并且尚未收到数据库生成的键值。在这种情况下,使用“添加”方法或“已添加”实体状态来跟踪图表,然后根据需要将非新实体的状态设置为“未更改”或“已修改”。
当我调试时,我看到dbSet仍然包含在构造函数控制器中检索的实体。所以我的问题是我如何阅读它,以及这种模式应该如何工作,因为每次需要更新时我都可能在更新之前检索一个对象。
以下是我的通用存储库的相关代码:
public ICollection<TDomain> Recuperer(Expression<Func<TObject, bool>> filter = null,
Func<IQueryable<TObject>, IOrderedQueryable<TObject>> orderby = null)
{
IQueryable<TObject> query = dbSet;
if (filter != null)
{
query = query.Where(filter);
}
List<TDomain> objects = new List<TDomain>();
foreach (TObject o in query)
{
objects.Add(Mapper.Map<TObject, TDomain>(o));
}
return objects;
}
public void Update(TDomain entity)
{
TObject o = Mapper.Map<TDomain, TObject>(entity);
dbSet.Attach(o);
context.Entry(o).State = EntityState.Modified;
}
谢谢!
更新:
我忘记了Generic Repository的重要定义:
this.context = contextInjected;
dbSet = context.Set<TObject>();
答案 0 :(得分:1)
我认为最快的解决方法是将Recuperer
中的第一行更改为
IQueryable<TObject> query = dbSet.AsNoTracking();
这将阻止对象附加到上下文。
更基本的解决方案是从DbSet.Local
集合中查找附加用户,将属性从TDomain entity
复制到其中,以便更改跟踪器将修改实体状态本身,更新查询将仅更新修改后的属性。