Recently I was working on a data-driven application which needed to continue operating in sometimes-disconnected environments. In theory, this is a fairly simple problem to solve with .NET Sync Framework using a “Local Data Cache” implementation of SQL Server CE file and SQL Server database–a solution that I have implemented several times in the past.
Never have I had to jump through so many crazy hoops.
I’ll be the first to admit that I am not a database expert, nor a Sync Framework guru–but I have used it in the past.
I started off as I always had in the past:
I created my database in SQL Server, then opened VS and created a new project for my Data Abstraction Layer (DAL). I added a “New Item…” and selected “Local Database Cache.”
After I completed the wizard and picked the tables I needed to synchronize, the synchronization ran successfully for the first time, I created my Entity Framework data entities, and everything looked ready to go!
I started to implement the DAL, and decided that my application would synchronize it’s DB cache with the server DB when it first launched. This required the following code:
// Call SyncAgent.Synchronize() to initiate the synchronization process. // Synchronization only updates the local database, not your project's data source. MinModelDataCacheSyncAgent syncAgent = new MinModelDataCacheSyncAgent(); Microsoft.Synchronization.Data.SyncStatistics syncStats = syncAgent.Synchronize();
However, the first time I ran the project, an “EntryPointNotFoundException” was thrown on the second line! I reran the project and received an “AccessViolationException” this time.
I spent the next 2 days searching on Google trying to figure out what exactly was going to solve the problem. After disabling my firewall and antivirus, cleaning and rebuilding the project, removing/re-adding/changing versions of references, re-installing the Sync Framework SDK, and re-creating the problem in new test projects, I was about ready to stop Microsoft Development for good! One website suggested that the issue could be caused by mismatching versions of the SQL CE provider.
This seemed unlikely to me, since I was not deploying the project anywhere–I was simply running it inside of VS2010! And the synchronization had no problems everytime I opened the .sync file through the IDE and ran the synchronization through the Wizard. Was it really possible that VS2010 was targeting one DLL for it’s synchronization wizard (which worked) while adding a reference to a different DLL to the project (which did not work)?
After 2 days and a huge headache I was desperate and ready to try anything. I uninstalled everything from my computer that had the words “Sync Framework” in it except for the packages which were required by VS2010:
- Microsoft Sync Framework Runtime v1.0 SP1 (x86)
- Microsoft Sync Framework Services v1.0 SP1 (x86)
- Microsoft Sync Services for ADO.NET v2.0 SP1 (x86)
Then I updated all of the references in my projects to make sure they were all pointed at the only versions of Sync Framework libraries I had installed, and I ran the project again with my fingers crossed…
A new exception! “The specified change tracking operation is not supported. To carry out this operation on the table, disable the change tracking on the table, and enable the change tracking.”
Progress! I double checked my sync settings through the VS2010 wizard and confirmed that I was not using SQL Server change tracking and that the synchronization through the wizard was still working as it had always worked. It was.
I set off to Google my problem once more, and fairly quickly discovered a potential solution: don’t copy your .sdf to the output directory.
I changed the properties on my .sdf file and set it to not copy, re-ran my test project once again and for the first time it actually successfully synchronized the file without crashing!
I couldn’t believe it! I re-ran the project a few more times, and it seemed to keep working…
I’m still not quite sure what I did to fix the problem as I jumped through so many hoops and tried so many different things. It seems the issue was caused by having multiple versions of Sync Framework installed on my machine, and VS2010 being unable to consistently target a single version when it created the local cache file.