I am learning DDD (domain driven design) and also the repository pattern (in C#). I must have the ability to make use of the repository pattern to persist an entity and never care which database is really used (Oracle, MySQL, MongoDB, RavenDB, etc.). I'm, however, unsure how to deal with the database specific id:s most (all?) databases uses. RavenDB, for instance, mandates that each entity it will store comes with an id property of type string. Other may need an id property of type int. As this is handled in a different way by different databases, I am unable to result in the database id an element of the entity class. However it would need to exist sooner or later, a minimum of after i keep actual entity. My real question is exactly what the best practise in regards to this is?

The concept I'm presently going after would be to, for every database I wish to support, implement database specific "value objects" for every business object type. These value object would then possess the database specific id property and that i would map between your two upon reads and creates. Performs this appear like advisable?

This is actually the classic situation of seeping abstractions. You cannot possibly abstract away the kind of database within repository interface unless of course you need to loose all of the good stuff that include each database. The needs on ID type (string, Guid or whatever) are just the surface of huge iceberg with most of its mass underneath the muddy waters.

Consider transaction handling, concurrency along with other stuff. I realize your point about persistence lack of knowledge. It is a positive thing without a doubt not to rely on specific database technology within the domain model. However, you also can't eliminate any reliance upon any persistence technology.

It's relatively simple to create your domain model fully trust any RDBMS. Many of them have standardized data types. Using ORM like NHibernate can help you a great deal. It's harder to offer the same among NoSQL databases simply because they often differ a great deal (which is excellent really).

So my advise is always to do your homework on what's the group of possible persistence technologies you'll have to cope with after which choose appropriate degree of abstraction for that persistence subsystem.

If the will not meet your needs, consider Event Sourcing. The big event store is among the least demanding persistence technique. Using library for example Jonathan Oliver's EventStore will help you to use almost any storage technology, including file system.

You are able to potentially possess the ids within the entity although not expose it included in entity's public interface. You could do with NHibernate since it enables you to definitely map table column to some private area.

So that you can potentially have something similar to

class Customer {
        private readonly Int32? _relationalId;
        private readonly String? _documentId;

This isn't ideal since your persistence logic 'bleeds' on business logic but because of the needs it most likely is simpler and much more robust than maintaining mapping between entity and it is id somewhere outdoors entity. I'd also recommend you to definitely evaluate "Database agnostic" approach which may become more realistic should you simply want to support relational databases. Within this situation you can at any rate reuse ORM like NHibernate for the repository implementation. And many relational database support same id types. Inside your scenario explore just have ORM additionally you need something similar to "Object-Document-Mapper". I can tell that you may have to create boat loads of infrastructure code. I recommend you to definitely reexamine your needs and select between relational and document databases. Look at this: Pros/cons of document-based databases vs. relational databases

I'd proceed and make an int Id area within the entity after which convert that to some string within the repository in which the Id should be a string. I believe your time and effort to abstract your persistence is extremely worthwhile and really helps reduce maintenance.