【问题标题】:RavenDB ID prefix and REST APIRavenDB ID 前缀和 REST API
【发布时间】:2018-04-16 13:51:55
【问题描述】:

我目前正在为应该是微不足道的事情而苦苦挣扎,也许确实如此,但我找不到合适的解决方案。

我的问题源于 RavenDB 默认 ID 结构。假设我们使用 HiLo 算法创建一个人,我们将获得我们的第一个文档:

people/A-1

相关的集合“人物”现在有一个成员。

我的问题其实很简单:设计一个普通的RESTful方法来获取一个人:

GET people/:id

并使用示例文档 ID 调用它,我的调用将变为:

GET people/people/A-1

这显然不起作用,因为斜杠字符是路由分隔符,但对于 RavenDB,它也是实体 ID 的一部分。

我尝试使用不同的分隔符(更改我的客户端代码上的约定),以便获得像 people#A-1 这样的 ID,但 RavenDB Studio 无法识别:如果我尝试通过以下方式将两个文档“链接”在一起他们的 ID,只有标准格式被识别。我也找不到在服务器级别设置数据库约定的方法,但只能在客户端级别。

这个解决方案也感觉像是一种肮脏的解决方法,我正在寻找正确的做事方式。

我知道我可以使用任意 ID,例如不带任何前缀的电子邮件地址,但这对于我要存储的所有类型的实体来说是不可行的,自然键并不是在每种情况下都可以选择的。

所以我想请教在使用 RavenDB 方面比我更有经验的人。解决这个问题的正确方法是什么?

【问题讨论】:

    标签: c# nosql ravendb ravendb-studio


    【解决方案1】:

    您只能将 1-A 传递给接收请求的控制器,因为 PeopleController 暗示您将使用 People,然后您可以使用 RavenDB 函数将前缀添加到 id:

    var collectionName = documentStore.Conventions.FindCollectionName(typeof(People));
    var idPrefix = documentStore.Conventions.TransformTypeCollectionNameToDocumentIdPrefix(collectionName);
    
    var id = idPrefix +"/"+ "1-A";
    

    否则您可以更改该类型的 id 生成约定

    【讨论】:

    • 这真的不是我想要的。我在解耦场景中工作,RavenDB 在 DAL 中被隔离。实体具有“Id”属性,仅此而已。如果有一种方法可以让 Raven 在通过省略前缀从数据库中检索实体时构造我的实体,那么我们就在做某事,否则我们就不是。
    • 如何加载实体?正如我所说,您可以更改 id 生成约定
    • 不像你说的那样。当您获得实体(使用查询或加载)时,“Id”属性将填充完整的 Id。另外,当你想通过“Id”查询时,你需要传递完整的Id。因此,假设我加载所有人员以填充列表,然后我想获取有关特定人员的更多信息。我首先需要 People 列表中的“Id”属性来包含完整的 Id,因为我将再次需要它来使用 Query 或 Load 加载特定的 Person。
    【解决方案2】:

    我没有在玩具项目之外使用过 ravendb,但是当我阅读 ayendes 的书时,我认为这会是一个问题。 我看到了三种可能的方法来规避这个问题:

    1. 分配一个 guid 作为 id,这样你的 id 中就没有 /。这可以在创建文档时完成
    2. 在每个控制器方法上将“/”替换为不太糟糕的内容,这很烦人且容易出错。
    3. 在生成 URL 时,对 id 部分进行 URL 转义。

    我想我会使用 #1。

    【讨论】:

    • 选项 2 可以在客户端的约定级别设置,在创建 Store 单例时。不过还是有点不方便。我希望得到开发者的官方回答。
    • 你用过 ravendb 谷歌论坛吗,我发现那里的响应非常好
    【解决方案3】:

    我遇到了同样的问题,我通过 GUID 更改了文档 ID 生成策略。要将文档 ID 生成为 GUID,您需要在您的实体的 Id 属性中传递 string.Empty

    var branch = new Branch.Model.Branch()
    {
       Id = string.Empty,
       Name = request.Name,
       Address = request.Address,
       ContactNo = request.ContactNo,
       Email = request.Email
    };
    
    await _session.StoreAsync(branch, cancellationToken);
    await _session.SaveChangesAsync(cancellationToken);
    

    在 RavenDB 中,服务器支持四个选项来存储文档并为其分配标识符https://ravendb.net/docs/article-page/4.1/csharp/server/kb/document-identifier-generation

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-27
      • 1970-01-01
      • 2020-05-21
      • 1970-01-01
      • 2015-04-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多