【发布时间】:2014-02-12 14:12:11
【问题描述】:
我希望这将是一个简单的问题,但对于我的生活,我无法在 SO 或任何其他网站的其他地方找到具体答案。
我有一个使用实体框架代码优先的基本存储库/工作单元模式。除了某些更新情况外,这一切都很顺利。问题是我有一组实体框架模型对象,它们都以 EF 返回的“Db”为前缀,但我随后将它们转换为普通的 DataContract 模型对象以传递给 Web 层以实现关注点分离。我有一个基本的转换接口,它只是从 DataModel 对象中填充一个 WebModel 对象,逐个字段逐字复制。
因此,如果您从 EF 检索 ID 为 1 的 DbUser 对象,然后转换为 User 对象,然后将该 BACK 转换为 DbUser 对象,您最终会得到 ID 为 1 的 DbUser,但它是一个不同的对象对于您开始使用的对象,尽管它们具有相同的主键字段,但实际的 CLR 对象本身是不同的。
以下作品
User user;
using (var work = new UnitOfWork())
{
var repository = new UserDataRepository(work);
user = repository.Get(1);
repository.save();
}
var modelUser = DataConverter.Convert(user);
modelUser.Name = "new name";
user = BusinessConverter.Convert(modelUser);
using (var work = new UnitOfWork())
{
var repository = new UserDataRepository(work);
repository.Update(user);
repository.save();
}
由于它们使用两个不同的工作单元/上下文,因此第二个块在 ObjectStateManager 中没有可比较的内容,并且可以在 Update() 方法中附加分离的对象
这不起作用
using (var work = new UnitOfWork())
{
var repository = new UserDataRepository(work);
user = repository.Get(1);
repository.save();
var modelUser = DataConverter.Convert(user);
modelUser.Name = "new name";
user = BusinessConverter.Convert(modelUser)
repository.Update(user);
repository.save();
}
注意:从逻辑上讲,我知道转换并只是转换回来没有多大意义,但是继续使用它,我已经大大简化了示例以使其更容易写在纸上,在我的实际代码中是有原因的因为那样做。
我收到常见错误“objectstatemanager 中已存在具有相同键的对象...”。我假设因为 Get() 将对象加载到 EF 中,然后更新看到该对象已分离,然后尝试附加它并且它已经存在。
我的存储库中的更新方法如下
public override bool UpdateItem(DbUser item)
{
if (Work.Context.Entry(item).State == EntityState.Detached)
Work.Context.Users.Attach(item);
Work.Context.Entry(item).State = EntityState.Modified;
return Work.Context.Entry(item).GetValidationResult().IsValid;
}
【问题讨论】:
-
为什么不使用工作方法?
-
解释起来有点复杂,但基本上我的 Web 服务方法之一需要从数据库中获取“帖子”,更新查看计数以显示新用户查看了此帖子,并将帖子返回到网络层。这涉及同一 UnitOfWork Web 方法中的 Get 和 Update。对于测试框架来说也非常不方便,因为每次我获取或更新存储库时,我都需要销毁并重新创建一个新的工作单元
标签: c# entity-framework ef-code-first repository