Skip to main content

Entity Framework–Multiple Database support

One of the limitations that EF still has is the support for multiple databases. It simply does not support that option.out of the box. Allthough on UserVoice a lot of people have voted this feature, it still doesn’t exist.

Credit where credit is due: this is not my original idea. I first downloaded the original script, used it and then i almost completely rewrote it to suit my needs and to improve certain aspects. I love Linq, so i used it a lot. The original and fantastic script can be found here

The trick is making EF believe that those objects are in the database by using synonyms. I dont know if every EF-supported database allows synonyms or not, but this is possible in SQL Server (which i am using).  

My script adds the ability to backup the edmx files first (which i find useful to prevent my model from being corrupted), replace the prefixes in the resulting model (which i had to do by hand with the other script) and finally reorder the navigation properties by alphabetical order. This last one is a must for me, because i use LINQPad a lot and the properties appear as links in the order they are declared. Another change include the ability to import the Function Imports declared (if i’m not mistaken the original script would throw an exception for the lack of an attribute in the FunctionImport element)

The following procedures must be taken for this approach to work. I know it seems a lot, but you may benefit much more from it.
  • Define a database that will have all the synonyms for other database objects. This will be your entry point in EF. It can be any database
  • Create synonyms for all foreign objects on your previously defined database. I find it useful to generate a script for the effect which selects a string for every table and then create those synonyms from the script results. Here it is:


  • Create one model for each database you want to merge.

  • Configure the variables in the script. You need to configure the directory of your models, the backup destination and the result file path. There still are similarities with the original script in this. Your can pass as many database paths as you like. Don’t forget to change the XNamespace’s in the begining of the script. They can vary depending on your EF version.

  • Go to the method ReplacePrefixes and configure the variable “CorrectPrefix”. This variable should contain the name of the Conceptual Model of your Main model, the one you created for your entry database. Finally, add new replaces for your other databases in the line where the replace happens.

  • Backup everything manually to a safe location first. Things can go wrong.

  • Run the script, open and validate your principal edmx to check if everything went smooth. 

Limitations
  • The script is a workaround to when you need this kind of feature. It’s a shame EF doesn’t support this, and we have to live with that. Entities will not be removed from the main edmx if they were deleted from any leaf module. I didn’t need this feature, so i didn’t implement it.

  • I cannot garantee that this script will work in all cases. The model i use is not that complex and doesn’t cover all use cases, so some features may be missing.

  • Navigation properties between entities from the merged models are supported. Just be sure you name them with the “LNK_” prefix. This allows me to verify while merging and to keep those rather than overwrite them. My approach is exactly the same as the original script. If you prefer, you can change this prefix in the MergeEDMX method.

  • Take care with objects with the same name between models. If a conflict should exist, your model will become corrupted and you have to modify it manually or restore backups.

  • When you have to import the model from the database, do it always on the leaf models (except when you are importing from the database of your main model, of course) and then merge it.

  • Every time a change occurs in one of the leaf models, you need to merge it again with the main model.

Enough talk! Here is the script, make good use of it!



Disclaimer: Remember to test the script before using it. This is a workaround and is not perfect, may contain bugs or unexpected behavior. Use at your own risk.

Keep coding.

Comments

Popular posts from this blog

The repository's repository

Ever since I started delving into architecture,  and specifically service oriented architecture, there has been one matter where opinions get divided. Let me state the problem first, and then take a look at both sides of the barricade. Given that your service layer needs to access persistent storage, how do you model that layer? It is almost common knowledge what to do here: use the Repository design pattern. So we look at the pattern and decide that it seems simple enough! Let's implement the shit out of it! Now, let's say that you will use an ORM - here comes trouble. Specifically we're using EF, but we could be talking about NHibernate or really any other. The real divisive theme is this question: should you be using the repository pattern at all when you use an ORM? I'll flat out say it: I don't think you should... except with good reason. So, sharpen your swords, pray to your gods and come with me to fight this war... or maybe stay in the couch?

The evolution of C# - Part III - C# 2.0 - Iterators

It's been a while since i wrote the last post, but i did not forget my purpose of creating a series that shows the evolution of C#. Today i came here to talk about one of the most useful features of C#, even if you dont know you're using it. Let's talk about iterators ! What is an iterator? For those of you who didn't read about the iterator pattern somewhere in the internet or in the "Gang of Four" book, you can read a description  here . The iterator is a class/object/whatever which knows how to traverse a structure. So, if you have a list or collection of objects, an iterator would have the knowledge of how to traverse that collection and access each element that it contains. The iterator is a well known design pattern and is behind many of the wonderful that we have nowadays in .NET (Linq comes to mind). Why is it a feature? Truth be told, an iterator is a concept well known way before .NET even existed. Being an OO Design Pattern, the iterator has

My simplest and most useful type

I have been doing some introspection on the way I write code to find ways that I need to improve. I consider this a task that one must do periodically so that we keep organized. There is a very, very simple problem that occurs in every application I know: How to return the results of an operation to the user? I've seen many implementations. Some return strings, some throw exceptions, some use out parameters, reuse the domain classes and have extra properties in there, etc. There is a myriad of ways of accomplishing this. This is the one I use. I don't like throwing exceptions. There are certainly cases where you have no choice, but I always avoid that. Throughout my architectures there is a single prevalent type that hasn't changed for years now, and I consider that a sign of stability. It is so simple, yet so useful everywhere. The name may shock you, take a look: Yes, this is it. Take a moment to compose yourself. Mind you, this is used everywhere , in every