Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create the database with Entity Framework Code First and DDD?

To implement domain driven design with the Entity Framework I use the approach Julie Lerman presented on TechEd North America 2013 (http://channel9.msdn.com/Events/TechEd/NorthAmerica/2013/DEV-B336#fbid=4tnuPF6L-Jc). This approach uses EF entity classes as domain classes. For different bounded contexts domain entity classes have different properties and may even be differently named, although they store their data in the same table. Example is a customer in the "Customer Service" bounded context that is in fact a "Customer", but in the "Shipping" bounded context he is a "Recipient" with only a subset of the customer properties. For each bounded context a different EF context exists that includes only DbSets for the entities the bounded context needs. By overriding OnModelCreating we can even exclude referenced entities that have nothing to do with the bounded context. This part is fairly easy to implement using POCOs.

The problem is the database creation when using Code First. If we let Code First create the database for each different EF context we end up with several databases. If we define the database name in the EF context's constructor the database is created with the first used EF context and we get an InvalidOperationException (saying the model has changed) when the second EF context is used (missing entities, missing properties etc.). We possibly could use migrations to update the database if an EF context is used that uses entities/members other EF contexts before did not have. But that most certainly gets mixed up with the normal use of migrations and will not work properly. As a temporarily solution I use a separate EF context only for database creation. This means I have to implement all EF entities again just for this purpose. Another problem is that I must create an instance of this EF context on application start to ensure the database gets created and (if necessary) migrated.

I am sure that there are other solutions. So, please (Julie ) tell us how.

like image 985
Jürgen Bayer Avatar asked Oct 21 '22 00:10

Jürgen Bayer


1 Answers

In essence I believe you will have to have a master context that has all 'tables' defined and also drives migration. This context is what is used to create the database.

All subsequent 'bounded' contexts would have Database.SetInitializer(null) in their constructor to prevent them from tampering with the database schema.

Further both your master context and your 'bounded' contexts should inherit from an abstract base context class that has the connectionstring and such set.

When you application starts you could simply attempt to instantiate your master context and make sure it's migrated to the latest version. But in your actual application later on you only use your 'bounded' contexts that only implements a subset of your master context.

I realize you are already doing some of this in part or whole but I think that is the way to go.

like image 61
Drauka Avatar answered Oct 27 '22 12:10

Drauka