Jürgen Bayer
Jürgen Bayer

Reputation: 3023

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.

Upvotes: 5

Views: 4041

Answers (2)

Drauka
Drauka

Reputation: 1217

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.

Upvotes: 2

phil soady
phil soady

Reputation: 11348

I agree with Julie Lermans suggestion. Indded she has been suggesting this approach for sometime. And you dont need EF6 to do so. Although it can be easier to manage with EF6.

Declare as many Contexts as you like. The key is the initialization setting of the Database during context creation. The basic pattern is as follows

eg

// when you wish to migrate
Database.SetInitializer(new MigrateDatabaseToLatestVersion<YOURCONTEXT, YourContentConfiguration>());
var connie = new YOURCONTEXT(.....);

//When you wish to access but NOT change the DB with a small context.
Database.SetInitializer(new ContextInitializerNone<BoundedMiniDbContext>());
var connie = new BoundedMiniDbContext(.....);

where yourContent inherits from DbContext and YourContextConfig inherits DbMigrationsConfiguration

Upvotes: 1

Related Questions