Question

My examples are going to involve pseudo C# code for discussion purposes, but this is not specific to any single language or database tooling.

Take a simple model

Customer { string Id }

Using RavenDB when I store new Customer() it will generate an id for me at execution time, suppose "Customers/234". In this scenario I'm fine with accepting that id is a facet of RavenDB. Fundamentally this is absolutely no different than Guid.NewGuid().ToString() as it creates an identifier that has no human understandable meaning and merely achieves the goal of global uniqueness (to this database). This is just arguably a nicer version of a guid, and will create better URLs and allow a human to communicate their id if it's ever needed far easier than a string of 16 random hex characters.

In another scenario take:

User { string UserName, string Id }

In this scenario I want to place true semantic meaning into my Id as opposed to just an unique number.

With RavenDB this could be accomplished similar to:

store.Conventions.DocumentKeyGenerator = (entity) => 
{
   User user = entity as User;
   if(user == null)
      return  defaultKeyGeneration (entity);

  return "Users/" + user.UserName;
}

Which then during this store operation you would end up with "Users/dotnetchris"

I could also approach this by instead of having User have a simple property for Id, to use a read-only property:

User {
    string Id { get { return "Users/" + UserName }

I'm having a hard time deciding which of these is the proper place for this construct.

I'm leaning towards it should be included in the class directly, as this gives you information that it will be easy to load this object by id from user input without actually needing to query to the datbase to find Users.Where(user.UserName == "dotnetchris")

Was it helpful?

Solution 2

As a rule I strive for every single identifier to be owned by the application and not the database. The only reason I will pass ownership of a model's identity is performance reasons, e.g. a SQL table that needs replicated and has 500 million rows.

OTHER TIPS

It seems highly dependent on how the data may or may not be referenced in the database. If the "full" ID (i.e. Users/name) is required for some kind of constraint in the database design, then keeping it close to the database would be a better option, but if that's not the case, you will benefit more from keeping it as a piece of the domain model to allow for flexibility in the code (as per your final code sample).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top