也许我不会以正确的方式解决这个问题,所以如果有人能指引我朝着正确的方向前进,我会非常感激。
我的代码中有很多类似
的方法void UpdateWidget(Widget updatedWidget)
{
IDocumentSession session = documentStore.OpenSession();
oldWidget = session.Load<Widget>("widgets" + widget.Id);
oldWidget.Name = updatedWidget.Name;
oldWidget.Color = updatedWidget.Color;
oldWidget.CreatedDateTime = updatedWidget.CreatedDateTime;
session.SaveChanges();
}
我喜欢做什么类似于以下内容(假设ID当然相同)
void UpdateWidget(Widget updatedWidget)
{
IDocumentSession session = documentStore.OpenSession();
oldWidget = session.Load<Widget>("widgets" + widget.Id);
oldWidget = updatedWidget
session.SaveChanges();
}
有人可以用一些语法或模式帮助我,让我接近这个吗?有没有办法在Raven中使用对象跟踪来实现这一目标?或者我是否需要某种映射工具,如automapper(我不太了解)
提前感谢!
答案 0 :(得分:4)
您可以只存储更新的对象,如果已存在,它将替换旧的对象。
void UpdateWidget(Widget updatedWidget)
{
using (var session = documentStore.OpenSession())
{
session.Store(updatedWidget);
session.SaveChanges();
}
}
但是,您必须考虑并发效应。
如果禁用了乐观并发,它应该只接受新文档,但您可能会踩到其他更改。如果启用了它,则需要在同一会话中执行加载和更新,或者您需要自己跟踪文档的标签。
有关详细信息,请查看以下RavenDB知识库文章:http://ravendb.net/kb/16/using-optimistic-concurrency-in-real-world-scenarios
另外 - 与您的问题无关,但正确处理您的会话非常重要。用using
语句包装它。 (或者如果它被注入,那么请确保您的IoC具有适当的生命周期范围,并在适当的时候进行处理。)
答案 1 :(得分:1)
AutoMapper或类似的(Value Injecter)非常适合摆脱从一个对象到另一个对象的代码映射。
使用AutoMapper,您将替换
oldWidget.Name = updatedWidget.Name;
oldWidget.Color = updatedWidget.Color;
oldWidget.CreatedDateTime = updatedWidget.CreatedDateTime;
与
AutoMapper.Mapper.CreateMap<Widget, Widget>();
var oldWidget = AutoMapper.Mapper.Map<Widget, Widget>(updatedWidget);
应在应用程序启动时配置AutoMapper(.CreateMap)。