I have designed a database whose MDF file will be copied to remote offices, so basically I will have different databases wth the same scheme. However, some tables from these databases will have to contain the same data. First I was happy because I knew it was easy to sync them using RowVersion columns in each table, but then I remembered that primary key columns in these tables (columns named “ID”) are also identity columns. So I have no idea on how to synchronize them in way that they are identical. With same IDs and everything. Also I am doing this through Entity Framework, which sits between the SQL Server 2008 R2 Express and .NET Framework 4 WCF Service. Any clues?
Note that this is a one-way sync, remote offices need to replicate these tables from the main database but they are not able to modify them and write changes back.
The original thread was started here: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/e5f89bac-959c-490a-befc-a80d5aa9a9a5/ but I haven’t come to a solution yet. If you take a look at the thread I linked to, you will see that the proposed solution was to attach records from the main DB context to the client DB context and call “ApplyCurrentValues” method to update the client DB. However I have come to conclusion that it would not work at all due to these reasons:
- Different EntityKey values between data from two contexts. You can’t attach a record to a context if that record’s EntityKey doesn’t correspond with the context. To get past this issue I had to convert the object from mainDB to the object from clientDB using AutoMapper and set the EntityKey manually prior to attaching the record to clientDB context.
- If you want to add a new record (if one exists in mainDB but not in clientDB) you can’t use Attach. If the record you are trying to attach doesn’t exist in the store, EF will throw the exception back at you.
- If you want to add a new record, you must use AddObject, but that implies the EntityKey is generated automatically and you will not have control over the identity column. If you try to set EntityKey manually prior to adding a new record, EF will throw an exception at you.
So, the question is, how can I replicate data from the main DB to the client DB using EntityFramework?
We have recently implemented this solution, however our database was simple enough and we had one meta server (we call it meta as it is our server which holds only identities) and we have data servers. We have three data servers doing three way sync. Now originally we only had three servers, but inserting new IDs were problem and we didnt want to use GUID as well because it is not human readable.
So we introduced concept of IdentityServer (we called it MetaServer), which hosts a simple Web Service and simple database, database consists of Tables with only Identities, Hash and LastUpdate, Hash and LastUpdate are used to validate synchronization.
For example, following two tables are there on Meta Server,
Now Data Servers will contain Tickets as follow,
And our Save method on ObjectContext looks like following,
To Perform syncing, I would suggest, add a table like this which will Save every Change in Meta Server (Master Server)
Which then every data server can read from Meta Server and update changes…