2

出于讨论目的,我的示例将涉及伪 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")

4

2 回答 2

1

它似乎高度依赖于数据库中可能引用或不引用数据的方式。Users/name如果数据库设计中的某种约束需要“完整”ID(即域模型的一部分,以允许代码中的灵活性(根据您的最终代码示例)。

于 2012-03-21T21:15:41.060 回答
0

作为一项规则,我努力让每个标识符都归应用程序而不是数据库所有。我将传递模型标识所有权的唯一原因是性能原因,例如需要复制并具有 5 亿行的 SQL 表。

于 2016-01-26T16:11:53.363 回答