I need to develop an application that, for different customers, needs to target different existing legacy databases as persistence store, or that could also be able to run completely stand-alone with its own independent database.
So my approach is:
- Develop the domain model independently from the final persistence store
- Use an EF Code-First repository implementation to map it to its own standalone database if needed
- Use other repository implementations to map it to the legacy databases systems if needed
I know for a fact that one of the targetted existing systems is a CRM 2011 system. The "CRMRepository" implementation would best use the Microsoft CRM SDK I guess, instead of directly targetting the underlying SQL database.
But, CRM uses GUIDs as its primary keys for all its entities, while the other database systems will mostly use integers.
So I'm kinda confused on what the best approach is to design my domain entities to later not run into problems when mapping it to the persistence stores in the repository implementation.
A typical domain entity would be
public class Person
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
- For the standalone solution: use a code-first based EF repository, no problem
- For targeting an existing database with ints as Primary Keys: map it to the correct primary key property, no problem
- However, how to target a CRM backend ? A "Person" entity would typically map to the "Account" entity in CRM, however there the PK is accountid, which is a GUID, as with all other CRM entities.
Should I change my domain entities to use strings as primary key properties, so it can accomodate all kinds of datatypes, and then perform the conversion to and from the correct datatype inside each repository implementation ? Or are there other and better ways to tackle this ?
One of the things I thought of would be to declare all my 'Id' properties as type object, and then use the repository pattern along with Automapper to implement specific implementations and map my domain objects to for instance EF Entities (which would then have PKs of type int) in a EFRepository implementation.
For the CRM implementation of the repository, the repo would use the CRM SDK and map the 'object Id' on the GUIDs internally used by CRM.
Could that be a viable solution, or is it too far fetched ?
Thanks
EDIT 1: I'm open for commercial solutions. Could the use of LLBLGen be an option here ? Have zero experience with it but it looks like it does not allow you to reuse the same domain definition into separate "repository" implementations, or am I wrong ?
EDIT 2: Current solution structure overview, trying to follow onion architecture. Different repository implementations would go into "Infrastructure". Repository implementation would then be "pluggable" by customer by means of DI.