我正在尝试迁移现有的 Web 应用程序以使用 RavenDB。
我目前在我的 Web 应用程序中有页面,允许您根据查询字符串中的 id 查看类别、子类别和资源。
但是我注意到 RavenDB 为聚合根生成 id,但不为子实体生成 id。
我不认为子类别是聚合根(类别有子类别),所以我将其作为我的类别文档的子文档。
当我通过在查询字符串中传递的 id 直接访问它时,将其设为子文档是不是错了?但如果不是,我应该如何访问单个子类别,因为 RavenDB 似乎没有为不是聚合根的实体生成 id?
我正在尝试迁移现有的 Web 应用程序以使用 RavenDB。
我目前在我的 Web 应用程序中有页面,允许您根据查询字符串中的 id 查看类别、子类别和资源。
但是我注意到 RavenDB 为聚合根生成 id,但不为子实体生成 id。
我不认为子类别是聚合根(类别有子类别),所以我将其作为我的类别文档的子文档。
当我通过在查询字符串中传递的 id 直接访问它时,将其设为子文档是不是错了?但如果不是,我应该如何访问单个子类别,因为 RavenDB 似乎没有为不是聚合根的实体生成 id?
在 Raven 邮件列表上有一个关于这个确切情况的冗长而有趣的讨论。
简短的回答是,Raven 不是为此而设计的,只有根实体获得一个 id,其他一切都被视为值类型。但是您可以自己实现它,请参阅线程末尾的代码示例以获取信息。
我遇到了这个问题,但对让文档生成 ID 感到不舒服,因为我觉得它不是线程安全的,尤其是对于基于 Web 的环境。
最终我决定让服务器使用 GenerateDocumentKey 方法为我生成 id,如下所示:
using (var session = Store.OpenSession())
{
if(category.SubCategories != null)
{
var newSubCategories = data.BankAccounts.Where(x => string.IsNullOrEmpty(x.Id));
foreach (var sc in newSubCategories)
sc.Id = session.Advanced.Conventions.GenerateDocumentKey(sc);
}
session.Store(data);
session.SaveChanges();
}
通过这种方式,我允许数据库生成子 ID,并且可以确保我不必在实际类本身中满足竞争条件等。