在RavenDB中更新操作中的对象映射/复制的c#库或帮助器?

时间:2012-12-27 10:37:13

标签: mapping ravendb

也许我不会以正确的方式解决这个问题,所以如果有人能指引我朝着正确的方向前进,我会非常感激。

我的代码中有很多类似

的方法
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(我不太了解)

提前感谢!

2 个答案:

答案 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)。