1

I have a project that will be built incrementally.

The project is a desktop application, with Entity Framework with packages laid out like so:

Entity Framework + DAL -> Application + Logic etc

Version 1.0 had 2 objects:

  • Blog
  • Post

So I package it up and send it off to my client, he wants a few changes and I make further progress with the system as a whole.

Version 2.0 now has 3 objects:

  • Blog
  • Post
  • User

With Entity Framework the database schema no longer matches V1.0, the first version is now dead because of this and an error is thrown. I want my client to still be able to use version 1.0. How could/should I have built my application to allow the continued use of V1?

Edit for EnglishBob:

I want my Client to still be able to use V1. Say he has a testing department and they need to be able to use their LIVE DB or he has difficulty in scaling out the application across departments effeciently so must have both v1 and v2 running concurrently.

9
  • It will be extremely difficult. ORMs are not known to handle schema changes well. Commented Aug 16, 2014 at 9:50
  • I know this, but surely a few people have tried and failed/succeeded I would like to know how. I.e. a Layer between them with an API that is always current, or a way to run EF ignoring the updated changes. Commented Aug 16, 2014 at 9:57
  • 1
    What you can do: 1. Use code first and build a chain of diff contexts in an inheritance chain, 2. Determine the db version at load time and load the correct context Commented Aug 16, 2014 at 9:58
  • This is easiest if your schema changes are restricted to adding tables. For entity-level changes, you'll further need to handle null fields. Commented Aug 16, 2014 at 9:59
  • 1
    The central idea of oop inheritance is to handle versioning Commented Aug 16, 2014 at 10:44

2 Answers 2

2

One option would be wrapping your business logic by RESTFUL Webservices, so that the client not directly access the database, but only the versioned data returned by the service and the OR-mapping takes place at the Server side. In RESTFUL Webservices each representation of objects is identified by a special uri like "www.example.com/rest/api/2/posts" where 2 means Post representations of version 2. REST representations can be different from the storage of the target objects in the database. On the client side a http client is needed, to obtain the json or xml representation and the client must transform it to the POCOs. In java with JAXB the classes can be annotated, so that the serialization and deserialization processes are done by the framework. Maybe .NET supports such annotations too. If a new column is introduced your client could ignore it, but if a column is deleted, altered or the relationships changed the version must be increased to 3 and the uri with version 2 must return a representation the old client already understands. I think without having an additional layer on the server side, versioning of complex changes in the database is nearly impossible. One simple example would be a user with a one to one relation to address, that will be changed to one to many.

Sign up to request clarification or add additional context in comments.

8 Comments

Thank you, this is the way I have planned to version my application. Have you considered alternatives and is this the best and/or only way?
Exposing the db as rest service means you're dumping the versioning on the client, who cannot use ef nor prefab proxies. Not recommended unless a last resort.
The problem is that the client knows nothing about future changes. If the only changes would be new added columns the database could be designed with key, value and type, where the key is the name of the field, and type says the client in what type the value must be casted. In android such concept is used for the ContactsProvider, where data from different datasources can be stored (see the relations with Data in this link ->developer.android.com/guide/topics/providers/…).
The question is to do versioning with ef. If ef can be ditched, there are multiple low-level ways to handle db versioning. But then you lose the ORM capabilities of ef.
I think as long as the DTOs are detached they will 'carry' their own version as they will not included future changes once published. As long as the client can then 'speak' to the right version API the theory holds.
|
0

Best to maintain 2 DB's, a test and a production one. Point your client at the production DB and develop on the test one. Once you have sent V2 to your client update the production DB and let him know V1 is now obsolete.

I don't see any other way round this if the DB schema has changed.

3 Comments

I want my Client to still be able to use V1. Say he has a testing department and they need to be able to use their LIVE DB or he has difficulty in scaling out the application across departments effeciently so must have both v1 and v2 running concurrently.
Thanks for the info Smithy. I think in practice you will find maintaining backwards compatibility for the previous interfaces a lot of hassle and it will increase the complexity of your app. All it does is move the problem from the the client to the server for more work. Although if that's what the client needs I suppose there is no choice, good luck with the project! :)
Spot on @englishbob I'm having difficulty with a project at the moment thankfully it's only for 1 client, but we're looking at scaling over the next few months. I need to prepare now :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.