出于讨论目的,我的示例将涉及伪 C# 代码,但这并不特定于任何单一语言或数据库工具。
取一个简单的模型
Customer { string Id }
在我存储时使用 RavenDBnew Customer()
会在执行时为我生成一个 id,假设“Customers/234”。在这种情况下,我可以接受 id 是 RavenDB 的一个方面。从根本上说,这与创建一个没有人类可以理解的含义的标识符完全没有区别Guid.NewGuid().ToString()
,并且仅仅实现了全局唯一性的目标(对于这个数据库)。这可以说是一个更好的 guid 版本,并且将创建更好的 URL 并允许人们在需要时传达他们的 id,这比 16 个随机十六进制字符的字符串要容易得多。
在另一种情况下:
User { string UserName, string Id }
在这种情况下,我想将真正的语义含义放入我的 Id 中,而不仅仅是一个唯一的数字。
使用 RavenDB,这可以类似于以下方式完成:
store.Conventions.DocumentKeyGenerator = (entity) =>
{
User user = entity as User;
if(user == null)
return defaultKeyGeneration (entity);
return "Users/" + user.UserName;
}
然后在此存储操作期间,您最终会得到“用户/dotnetchris”
我也可以通过使用只读属性而不是让 User 有一个简单的 Id 属性来解决这个问题:
User {
string Id { get { return "Users/" + UserName }
我很难决定哪一个是这个构造的合适位置。
我倾向于它应该直接包含在类中,因为这为您提供了这样的信息:通过用户输入的 id 加载该对象很容易,而实际上不需要查询数据库来查找Users.Where(user.UserName == "dotnetchris")