【问题标题】:Custom key generation in RavenDBRavenDB 中的自定义密钥生成
【发布时间】:2012-10-07 20:48:29
【问题描述】:

我有一组实体,它们都是从抽象类派生的

public abstract class NamedEntity : INamedEntity
{
    #region Public Properties

    public string Description { get; set; }

    public string Id { get; set; }

    public string Name { get; set; }

    #endregion
}

当我持久化所有实体时,我想使用 Name 字段作为键,所以我覆盖 DocumentKeyGenerator 并提供这样的实现:

    store.Conventions.DocumentKeyGenerator = entity =>
        {
            var namedEntity = entity as NamedEntity;

            if (namedEntity != null)
            {
                return string.Format("{0}/{1}", store.Conventions.GetTypeTagName(entity.GetType()), namedEntity.Name);
            }

            return string.Format("{0}/", store.Conventions.GetTypeTagName(entity.GetType()));
        };

当我第一次持久化实体列表时它工作正常,但如果我想再次持久化它们,我会遇到异常

PUT attempted on document 'xxxxx' using a non current etag

我刚开始使用 RavenDB,所以我不明白我做错了什么?

【问题讨论】:

    标签: c# nosql ravendb document-database


    【解决方案1】:

    只是猜测,但可能与您的密钥生成无关,而是您如何存储它们。

    在第一次使用时,您可能会遇到以下情况:

    var myEntity = new MyEntity(...);
    session.Store(myEntity);
    ...
    session.SaveChanges();
    

    那部分很好,但在以后的使用中,你不应该做同样的事情。相反,它应该更像这样:

    var myEntity = session.Load<MyEntity>("myentities/foobar");
    myEntity.Something = 123;
    ...
    session.SaveChanges();
    

    请注意,进行更改时不会调用.Store()。这是因为实体被会话“跟踪”,当您调用.SaveChanges()时,对它的所有更改都会自动持久化

    【讨论】:

    • 所以如果我从外部源获取实体集并且只想刷新我的持久化实体,我是否应该迭代所有这些实体,重新分配它们的值,然后保存更改?此外,如果我让 RavenDB 为我的实体生成唯一密钥,我的代码工作得很好,我可以重复这种行为来生成我自己的密钥吗?有什么区别?
    • 你确实可以做到。如果您有很多文档要一次全部更改,您可能需要研究修补 API。 ravendb.net/docs/client-api/partial-document-updates
    • 如果你让 raven 生成唯一的 id,并且你存储了一个新实体,它可能不会抛出你看到的异常,但你实际上是在存储一个新文档,而不是更新现有文档。完成后会有两个。
    猜你喜欢
    • 2018-12-04
    • 2017-08-09
    • 2017-10-04
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 2021-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多