2

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

我的代码中有很多方法可以执行类似的操作

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

提前致谢!

4

2 回答 2

4

您可以只存储更新的对象,如果它已经存在,它将替换旧的对象。

void UpdateWidget(Widget updatedWidget)
{
    using (var session = documentStore.OpenSession())
    {
        session.Store(updatedWidget);
        session.SaveChanges();
    }
}

但是,您必须考虑并发影响。

如果您禁用了乐观并发,它应该只接受新文档,但您可能会踩到其他更改。如果您启用了它,您需要在同一会话中执行加载和更新,或者您需要自己跟踪文档的 etag。

查看以下 RavenDB 知识库文章了解详细信息:http ://ravendb.net/kb/16/using-optimistic-concurrency-in-real-world-scenarios

还 - 与您的问题无关,但正确处理您的会话非常重要。把它包装在一个using声明中。(或者如果它被注入,那么确保你的 IoC 具有适当的生命周期范围,并在适当的时候处理它。)

于 2012-12-27T16:17:29.713 回答
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)。

于 2012-12-27T10:43:13.143 回答