Should Entities in Domain Driven Design and Entity Framework be the same?
Asked Answered
R

4

17

I have started using Entity Framework Code First for the first time and am impressed by the way in which our greenfield application is being built around the domain rather than around the relational database tables (which is how I have worked for years).

So, we are building entities in C# that are being reflected in the database every time we do a new migration.

My question is this: should these same entities (i.e. designed with Entity Framework in mind) play the same role as entities in Domain Driven Design (i.e. representing the core of the domain)?

Rego answered 4/11, 2014 at 15:33 Comment(0)
G
25

Object-Relational Mapping and Domain-Driven Design are two orthogonal concerns.

ORM

An ORM is just here to bridge the gap between the relational data model residing in your database and an object model, any object model.

An Entity as defined by EF concretely means any object that you wish to map some subpart of your relational model to (and from). It turns out that the EF creators wanted to give a business connotation to those by naming them Entities, but in the end nothing forces you that way. You could map to View Models for all it cares.

DDD

From a DDD perspective, there's no such thing as "an Entity designed with EF in mind". A DDD Entity should be persistence ignorant and bear no trace of any ORM. The domain layer has no interest in how, where, whether or when its objects are stored.

Where the two meet

The only point where the two orthogonal concepts intersect is when the object model targeted by your ORM mapping is precisely your domain model. This is possible with what EF calls "Code first" (but should really be named regular ORM), by pointing to your DDD Entities in separate EF mapping files living in a non-domain layer, and refraining from using EF artifacts such as data annotations directly in your Entity classes. This is not possible when using Database First, because the DDD "purity" part of the deal wouldn't be met.

In short, the terms collide, but they should really be conceptually considered as two different things. One is the domain object itself and the other is a pointer that can indicate the same bunch of code, but it could point to pretty much anything else.

Gretchen answered 5/11, 2014 at 11:39 Comment(4)
But when you use code first few framework reference are added.For example using System.ComponentModel.DataAnnotations.Schema . How it is bear no trace of any ORM? Can you please explain?Coreligionist
@Coreligionist System.ComponentModel.DataAnnotations.Schema is not part of Entity Framework. It can be useful in the domain layer but you don't have to reference it in entity classes.Gretchen
@Gretchen So are domain objects and entities different classes and should be kept in separates packages (example com.xyz.domain.Person and com.xyz.entities.Person ) ?Custos
No, entities are one kind of domain object. And I mean entities in the DDD sense of the word, not the EF sense.Gretchen
C
18

They shouldn't be the same as they're designed for different purposes. An ORM entity is a facade for 1 or more tables, its purpose is to simulate OOP on top of relational tables. A Domain Entity is about defining a Domain concept. If your Domain Entity turns out to be just a data structure, then you can reuse it as an EF entity, but that's just one case.

A DDD app never knows about EF or ORM. It only knows about a Repository. Hence, your Domain Objects (DO) don't know either about EF. You can choose to consider them EF entities, as an implementation detail, BUT... you should do that ONLY after your DOs are defined and their use cases implemented. You should defer as much as possible the implementation of persistence (use in-memory repos (lists) for devel).

When you reach that point you'll know if you can reuse your DO for ORM purposes or if you'll need other ways (such as a memento).

Note that a design of a DO while driven by the Domain, it should take into consideration the persistence issue, but it shouldn't be influenced by it i.e don't design your DO according to the db schema. The persistence strategy can be different for each DO and it might involve or not an ORM.

If you're using Event Sourcing for a DO, ORM doesn't exist. Same for serialized objects. It matters a lot how an object will be used by the app (updating and querying), that's why I've said you should defer the persistence implementation. For a lot of DOs you won't need a rdbms (even if you're using it) so an ORM entity will look more like a KeyValuePair (Id => serialized data).

In conclusion, they are different things for different purposes, that might look identical for some cases (CRUD scenarios).

Cannot answered 4/11, 2014 at 18:19 Comment(3)
Good point about the structure of the domain objects ideally not being influenced by the persistence mechanism. Thanks!Rego
Also read Vaughn Vernon's latest "Modeling Aggregates with DDD and Entity Framework" vaughnvernon.co/?p=879Thompkins
The above Vaughn Vernon link can now be found here: kalele.io/modeling-aggregates-with-ddd-and-entity-frameworkCountable
A
7

I would say, they can be the same.

Sometimes there is no need to support two models. When you follow code first approach, your entities model your domain, your infrastructure (ORM) separates domain and persistence layers.

It might be reasonable to maintain two models if you have legacy database and have to maintain it.

There are two other SO questions that can be helpful:

Abrego answered 4/11, 2014 at 17:5 Comment(0)
B
2

Well. That's the approach I use. And I've seen a lot of others doing the same. Now am using The Onion Architecture/Pattern to create my application and making everything rely on the domain entities made my life easier. Because whenever I want to change for example the layer that deal with my database, I can do that without changing the UI layer (ASP.NET MVC app, WPF app, etc.)... I suggest doing the same.

Let's wait for other posts.

I agree with what MikeSW said (3rd answer). When you design your domain entities, you should do that without caring about who will consume those entities (ORMs or any other technology serving whatever purpose). Design them with one idea in mind: they will be reusable and they will not need to be changed in the future (hopefully).

Barcus answered 4/11, 2014 at 17:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.