I understand the concepts in DDD but in practise it gets a bit confusing.
I am using C#, SQL Server and EF. I see that based on my database schema, the persistence models would look different from my aggregates. In order to define clean, nice aggregates, entities and value objects, my domain models would look different from the database models.
Moreover, if I try to merge these 2 then somehow I try to design my domain models more based on technology, not on domain.
Maybe a more concrete example would be for example:
Do I need to add an ID field in the entity if that id is used just for DB?
In case of Many2Many relationships it can also get tricky
Are these 2 models different and the implementation of the repository must convert db model into domain model or I should make the domain models the same as the models used by EF?
That's a common issue when you start with DDD.
They are completely separate things.
A Domain Model is an abstraction. It should not concern itself about the technology that you are using and it doesn't represent database tables, documents, classes, functions etc.
The Domain Model represents concepts, dependencies and interactions between these concepts.
Technology is used for the Implementation of a Domain Model.
Different technologies can be used to implement the same Domain Model.
As much as we would like to have the freedom do do whatever we like with your domain models, in practice we do use a technology for it's implementation and sometimes this will affect it.
Of course you can dump all frameworks and libraries and make your own solutions that will make your implementation a lot easier. Even if you do this you are still left with your language, C#, Java, Ruby etc... and the tools that it provides you.
Here's an example:
Let's say we develop a system for car rentals. A person can rent a car. In our Domain we have the concept of an Account that a Person has, a Car and a CarRental.
That's your Domain Model. At this point we are not concerned with the language, database or anything
Now to the Implementation of the Domain Model.
We will use C#. Now we need to decide for a database. If we decide to use SQL, we may decide to use the nice abilities of RDBMS to do joins so we may implement it by using integer IDs this way:
public class Account {
public int ID { get; private set; }
// other stuff
}
public class Car {
public int ID { get; private set; }
// other stuff
}
public class CarRental {
public int AccountID { get; private set; }
public int CarID { get; private set; }
// other stuff
}
On the other hand we may decide that integer ID's are not good because you can get collisions if you have to work with other systems and move databases and stuff, so we decide to think a bit and use an e-mail as a unique identifier for the Account and the license place as a unique identifier for the Car:
public class Account {
public Email Email { get; private set; }
// other stuff
}
public class Car {
public LicensePlace LicensePlace { get; private set; }
// other stuff
}
public class CarRental {
public Email AccountEmail { get; private set; }
public LicensePlace CarLicensePlace { get; private set; }
// other stuff
}
If we follow DDD and divide your Entities into Aggregates properly, you should not need to do joins between them as they should not be loaded or changes in the same transaction.
On the other hand, we may want to build a different model (read model maybe if we use CQRS, or we may need to extract reports) on top of the same database and using the second approach can make this harder since we loose the ability to do joins.
On the other hand, if we use a NoSQL database like MongoDB for example, we don't have the ability to do joins. So using integer ID's doesn't bring us any value.
Even if we decide use a SQL database and don't use integer ID's we can still use Domain Events and build additional models and reporting using them.
Also using joins won't work if we have a distributed system, so using integer ID's may not bring us any value at all.
Sometimes it's convenient to use the abilities of your technology to make some things easier, but we let it harm our Systems and Domain Models.
We end up building system that are very robust from technological point of view but they don't do the things that they are supposed to do, and that makes them useless.
A useless system is useless no matter how good it's implemented.
If you haven't read the DDD book, read it. Eric Evans talks about how you technology can either help you or fight you all the way. Eric Evans also talks about how DDD allows for a freedom of implementation so that you don't have to fight your technology.
Another thing that we tend to do if think all the time about persistence. It's true that we persist things most of the time but that doesn't mean that a Domain Model is something that is Persisted to a database.
When I started programming, I started with computer graphics and modeling applications like 3DsMax and Maya. When I started to write applications that use the holly Database it was really weird to me how people don't think and don't know about their domains, just persist stuff and make them work and all they talk about is technology.
If you are into computer graphics you won't be able to write a single like of code if you don't know Math. So you start with learning Math. After you know some of it, then you can write code.
Let's take games for example. You may design a Physics Engine that models the Domain of physics . In this model you will have concepts like Work, Power, Gravity, Acceleration etc. It's not necessary to persist them. You do persist other concepts like Weight of your Player for example so that the Physics Engine will know how gravity should affect it, but still you don't persist Power to the database. It's still a Domain Model. Power, Work etc are functions, not entities of aggregates. They are still part of your Domain Model.
Let's say you want to build a Physics engine The thing is that if you want to build a Physics Engine you have to know Physics. Physics is complex. Even if you are a really good programming knowing in EF or SQL of whatever, it won't help you build Physics engines. Knowing the Domain of physics and being able to make a Domain Model of it and then Implement it is the key.
If you want to really feel the difference between a Domain model from Implementation, check this out, This domain can blow your mind before you get to any implementation.
Also check this article on modeling entities with DDD.
EDIT
Here is another article that explains differences between NHibernate and EntityFramework for Domain Modeling.
Related
My goal is async loading of related entities using DBContext.
Let imagine two projects. The first named MyApp.Domain and contains domain entities.
namespace MyApp.Domain
{
public class PlanPage
{
public Guid Id { get; set; }
}
}
namespace MyApp.Domain
{
public class PlanPageDay
{
public Guid Id { get; set; }
public Guid PlanPageId { get; set; }
}
}
The second project named MyApp.Infrastructure.EntityFramework and contains configuration of projection entities to database. It also contains class which extends domain entity and implements Entity framework specific logic.
namespace MyApp.Infrastructure.EntityFramework.Models
{
public class PlanPageEntity : PlanPage
{
private readonly ApplicationDbContext _applicationDbContext;
protected PlanPageEntity(ApplicationDbContext applicationDbContext)
{
_applicationDbContext = applicationDbContext;
}
public ICollection<PlanPageDay>? Days { get; set; }
public async Task<ICollection<PlanPageDay>> GetDays()
{
return Days ??= await _applicationDbContext.PlanPageDays
.Where(pd => pd.PlanPageId == Id)
.ToListAsync();
}
}
}
The purpose of this example is simple. We separate infrastructure code from domain code. Look how do we plan to use this concept:
// Entity initializing code. Placing somewhere in domain logic.
var plan = new PlanPage(/*some constructor arguments*/);
// Entity loading code. Placing somewhere in infrastructure implementation.
public async Task<PlanPage> GetPlanPage(Guid id)
{
return await _applicationDbContext.Set<PlanPageEntity>().FindAsync(id);
}
Note that we tell to Entity framework to use child class (PlanPageEntity) so it can handle all specific things that it can.
The question is: Is it possible to configure the EF so that it allows us to use this concept?
As requested here's a little more details for my opinion stated in the comments.
The main reason why I think your current approach is a bad idea is that it violates the separation of concerns design principle: when you are mixing domain models with data access models, you make your domain logic completely dependent on how you model the data in your database. This quickly limits your options because the database may have some restrictions on how you can model your data that doesn't fit well with the domain logic you want to implement as well as making maintenance difficult. E.g. if you decide to split up one DB table into two then you might have a big task ahead of you in order to make your domain logic work with those two new models/tables. Additionally, making performance optimizations in your database easily becomes a nightmare if not thought through ahead of time - and you shouldn't spend time thinking of optimizing your system before it's necessary.
I know this is a little abstract since I don't know much about your domain but I'm sure I could find more arguments against it.
Instead, separating data access models (and in general all external data models) from your domain models makes it much easier to maintain: if you need to make some changes to your database, you simply need to update the logic that maps the data from your data access models to your domain model - nothing in your domain logic needs to change.
In the examples you have given, you have already logically separated your domain models and data access models into two separate projects. So why not follow through with that thought and separate the two with a binding/mapping layer in-between?
Is it possible to configure the EF so that it allows us to use this concept?
Yes. Essentially you have DTO's, and your Entities derive from your DTOs. So when you fetch an Entity you can return it directly. But if you wouldn't be able to attach a non-Entity, so you'd have to map it. It's going to be inconvenient, and like 99.999% of bespoke entity and repository designs, will be ultimately a waste of time.
This is somewhat similar to the what EF already does for you. Start with persistence-ignorant Entity classes, and introduce persistence-aware runtime subtypes for scenarios that require them, which is basically just Lazy Loading.
I have read many articles about DDD and understood, that I should use my domain model classes in the Infrastructure level, so, I should use the same classes as Entity Framework infrastructure and use them to generate tables (code-first approach) etc. But my domain model can be fully different than Relational DB model.
Why I can't create one more model, infrastructure model, to create relational DB model and don't mix domain model with EF classes?
Consider this simple example:
Domain Model
public class Customer
{
public Customer(IRegistrar registrar)
{
this.registrar = registrar;
}
public int Age
{
get
{
// Just for this example. This will not work for all locals etc but beyond the point here.
var today = DateTime.Today;
return today.Year - this.DateOfBirth.Year;
}
}
public DateTime DateOfBirth { get; set; }
public int Register()
{
if (this.Age < 18)
{
throw new InvalidOperationException("You must be at least 18 years old");
}
int id = this.registrar.Register(this);
return id;
}
}
public interface IRegistrar
{
public int Register(Customer customer);
}
A lot of people when they do not have a domain model will do this in an MVC controller:
public ActionResult Search(Customer customer)
{
var today = DateTime.Today;
var age = today.Year - this.DateOfBirth.Year;
if (age < 18)
{
// Return an error page or the same page but with error etc.
}
// All is good
int id = this.registrar.Register(customer);
// The rest of code
}
There are a few issues with that:
What if the developer forgets to make the check for age before calling registrar? Many people will say, well that is a bad developer. Well whatever the case is, this type of code is prone to bugs.
The product is doing well so CFO decides to open up the API because there are many developers out there who are making great UI interfaces for customer registration and they want to use our API. So the developers go ahead and create a WCF service like this:
public int Register(Customer customer)
{
var today = DateTime.Today;
var age = today.Year - this.DateOfBirth.Year;
if (age < 18)
{
// Return a SOAP fault or some other error
}
int id = this.registrar.Register(customer);
// The rest of code
}
Now the developers can forget to make the check for age in 2 different places.
The code is also in 2 different places. If there is a bug, we need to remember to fix it in 2 different places.
If the company starts operating in places where the legal age is 21, we need to find all the places and add this rule.
If we are discussing the rules with BA, well we need to look through all the applications and find the rules.
In the above case we only have one rule: Age must be greater than 18. What if we had many more rules and many more classes? You can see where this will go.
EF Model
Your EF model may be like this:
public class Customer
{
public int Id { get; set; }
public DateTime DateOfBirth { get; set; }
// It may have a foreign key etc.
}
Application Layer Model
And your model for MVC view maybe like this:
public class Customer
{
// Or instead of Domain.Customer, it may be a CustomerDto which is used
// to transfer data from one layer or tier to another.
// But you get the point.
public Customer(Domain.Customer customer)
{
this.DateOfBirth = customer.DateOfBirth;
this.Age = customer.Age;
if (this.DateOfBirth.DayOfYear == DateTime.Today.DayOfYear)
{
this.Greeting = "Happy Birthday!!!";
}
}
public int Age { get; set; }
[Required(ErrorMessage = "Date of birth is required.")]
[Display(Name = "Data of birth")]
public DateTime DateOfBirth { get; set; }
public string Greeting { get; set; }
}
Here is a question: How many EF models have you seen with the Display attribute? I will let you decide if the EF model should concern itself with how it is displayed in the UI. Just the assumption that my EF model will be displayed in UI is wrong. Maybe the only consumers of my class is another web service. I don't think Display should be in the EF model but some may not agree with me; you make the call.
There are loads of questions on stackoverflow about people asking that sometime PropertyX is required and sometimes it is not, how can I do this? Well if you did not put Required attribute on your EF model and use your EF model in your view, then you would not have this issue. There will be one model for the view where PropertyX is a required field. That model will decorate PropertyX with the Required attribute, while another model for the view that does not require PropertyX will not decorate the property with the Required attribute.
ViewModels
And then you may have a viewmodel for a customer for a WPF application and you may have a javascript viewmodel for the frontend (KnockoutJS viewmodel).
Conclusion and answer to your question
So in conclusion, you can have different domain models than your entity models. Your domain model should be unaware of the database. If you decide to remove a column from one table due to normalization and put it into a table of its own, your entity model will be affected. Your domain model should not be affected.
I have read arguments on the net such as "this design takes too long, I just want to roll something out quickly and give it to the client and get paid". Well if you are not designing a product which will need to be maintained and features will be added to it but you are just designing a quick little site for your client then do not use this approach. No design applies to every situation. The point to take away is that your design should be chosen wisely with future in mind.
Also the conversion from entity model to domain to a model for MVC does not need to be done manually. There are libraries out there which will do this for you easily such as AutoMapper.
But I have to admit, there are tons of examples on the net and also in use in many applications where the entity models are used throughout the application and rules are implemented everywhere with loads of if statements.
Relation of this to DDD
When I read your question, I find something that catches the eye. It is this:
I have read many articles about DDD and understood, that I should use my domain model classes in the Infrastructure level, so, I should use the same classes as Entity Framework infrastructure and use them to generate tables (code-first approach)
To be honest, the best source of DDD knowledge it still the Blue Book. I know, I know, it is thick and hard to read. May be have a look at DDD Distilled by Vernon. The conclusion should be that DDD is not really about dealing with persistence but in deeper insight of the domain, better understanding your domain experts. Definitely, it says nothing about ORM.
Domain Model persistence
Domain models usually consist of objects (if we talk about object-oriented models) with state and behaviour. A model would have one or more entities and may be some value objects. In many cases you only have one entity per bounded context. Entities are grouped in Aggregates, that change together, forming transaction boundaries. This means that each change within the Aggregate is one transaction, no matter how many entities this change touches. Each Aggregate has one and only one entity, the Aggregate Root, which exposes public methods for others to work with the whole Aggregate.
So your Repository should take care of:
Persisting the whole Aggregate(no matter how many entities are there) within one transaction, for new and updated objects
Fetching the whole Aggregate from your persistence store, by its identity (Aggregate Root Id property)
You for sure will need some Queries but they can query how they want as soon as they do not amend the domain model state. Many add querying methods to the Repository but it is up to you. I would implement them as a separate static class with DbContext extension methods.
Models not matching each other
You mentioned that your persistence model does not match the domain model. This might be the case although for many situations it is not the case. There are a few ways of dealing with this:
Keep state separate of the behaviour and have it as a property in the domain object. Like Order with AddLine and so on, and OrderState with all these Total, CustomerId and stuff like this. Bear in mind that this might not work nice for complex aggregates.
Concentrate on the two main methods of the Repository that I mentioned above - Add and Get. Each Repository works for one type of Aggregate only and how you map between them is up to you.
Combined with the point above, you can reconsider using ORM and do something else. Basically you can just use ADO.NET but the easiest is to use some sort of document-oriented stuff like NoSQL although many would disagree. Check also this article about PostgreSQL JSONB storage as persistence.
Remember that the main point is to have the Repository that will do the work for you and potentially (probably this would never happen but still) use another store.
You might also be interested in another Vernon's article where he discusses using EF specifically.
For a project we are starting to look at persistence features and how we want to implement this. Currently we are looking at keeping Clean Architecture in mind, probably going for Onion Architecture. As such, we want to define a new outer layer which in which the persistence layer resides.
We're looking at various ORM solutions (we seem to be converging to Entity Framework) using SQLite as data store and we are hitting a snag: How should be manage ID's and deal with add/removal in some collection or move some instance between different collections.
In the core of our 'onion', we want to keep our POCO objects. As such, we do not want some kind of 'ID' property to be added in our business objects. Only inside the persistence layer do we want to have classes with object ID's. Because of this separation:
how should removing a business object from some collection cause a row to be deleted from the SQLite database?
More complex (at least I think it is), how should a POCO instance moved from 1 collection to another cause a foreign key of a SQLite databaserow to be changed? (Instead of removing the row and recreating it with the same values)
Looking around the internet I've yet to find an implementation somewhere that demonstrates a persistence layer in a Clean Architecture design. Plenty of high level diagrams and "depend only inward", but no source code examples to give a demonstration.
Some possible solutions that we came up with so far:
Have some lookup between POCO instances and their representative 'database model objects' (which have ID's etc) within the persistence layer. When saving the project state, business model objects will be matched with this database model objects and update the state for the matches accordingly. Then the object is persisted.
When loading a project, the persistence layer returns decorator objects of business objects that add an ID to the business object, which is only visible within the persistence layer by casting the objects to that decorator class. However, this prevents us from defining sealed POCO objects and seems to break the Clean Architecture design philosophy.
Option 1 seems costly in memory due to effectively doubling the business objects in memory. Option 2 seems the most elegant, but as I've written: it feels that it breaks Clean Architecture.
Are there better alternatives to there? Should we just go for Option 2 and take Clean Architecture more as guidelines than rule? Can someone point us to a working example in code (I did find a iOs example at https://github.com/luisobo/clean-architecture, but as I'm not literate in the language it cannot do much with it).
As others have mentioned in the comments, IDs are a natural part of applications and are usually required in other parts than persistence. So trying to avoid IDs at all costs is going to produce awkward designs.
Identity Design
However, identity design (where to use which IDs, what information to put in IDs, user defined vs system generated, etc.) is something that is very important and requires thought.
A good starting point to determine what requires an ID and what not is the Value Object / Entity distinction of domain-driven design.
Value objects are things that consist of other values and don't change - so you don't need an ID.
Entities have a lifecycle and change over time. So their value alone is not enough to identify them - they need an explicit ID.
As you see here, reasoning is very different from the technical point of view that you take in your question. This does not mean you should ignore constraints imposed by frameworks (e.g. entity framework), however.
If you want an in-depth discussion about identity design, I can recommend "Implementing DDD" by Vaughn Vernon (Section "Unique Identity" in Chapter 5 - Entities).
Note: I don't mean to recommend that you use DDD because of this. I just think that DDD has some nice guidelines about ID design. Whether or not to use DDD in this project is an entirely different question.
First of all, everything in the real world have ids. You have your social security number. Cars have their registration number. Items in shops have an EAN code (and a production identity). Without ids nothing in the world would work (a bit exaggerated, but hopefully you get my point).
It's the same with applications.
If your business objects do not have any natural keys (like a social security number) you MUST have a way to identify them. You application will otherwise fail as soon as you copy your object or transfer it over the process boundry. Because then it's a new object. It's like when you cloned the sheep Dolly. Is it the same sheep? No, it's Mini-Dolly.
The other part is that when you build complex structures you are violating the law of Demeter. For instance like:
public class ForumPost
{
public int Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public User Creator { get; set; }
}
public class User
{
public string Id { get; set; }
public string FirstName { get; set; }
}
When you use that code and invoke:
post.User.FirstName = "Arnold";
postRepos.Update(post);
what do you expect to happen? Should your forum post repos suddenly be responsible of changes made in the user?
That's why ORMs are so sucky. They violate good architecture.
Back to ids. A good design is instead to use a user id. Because then we do not break law of Demeter and still got a good separation of concern.
public class ForumPost
{
public int Id { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public int CreatorId { get; set; }
}
So the conclusion is:
Do not abandon ids, as it introduces complexity when trying to identify the real object from all the copies of it that you will get.
Using ids when referencing different entities helps you keep a good design with distinct responsibilities.
I am just trying to get out of my comfort zone of typical N-Tier architecture of Repository/Service/Presentation and have started looking at DDD with Aggregates and I have to admit I'm a little confused and was hoping someone could clarify the following example:
If I had an Entity called News, NewsImage and Customer which were all EF persist-able objects like so:
public class Customer
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
}
public class NewsImage
{
public virtual int Id { get; set; }
public virtual byte[] Data { get; set; }
public virtual News News { get; set; }
}
public class News
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual ICollection<NewsImage> NewsImages { get; set; }
public virtual Customer Customer { get; set; }
}
As I understand it these could be the objects we would use to persist the domain objects to the database but if we are using aggregates from the domain model we could have something like this:
public class NewsAggregate
{
public int Id { get; set; }
public string Name { get; set }
public void AddImageToNews(byte[] imageData)
{
// Hide NewsImage or that object and add the byte[] data here?
}
}
My questions are following and I would appreciate any clarification as I am certain I am misunderstanding the fundamental principles here:
Only the aggregate objects should be exposed to the presentation layer (or any consuming layer).
How do I handle converting/persisting the aggregate objects to the database, I could use mapping which is fine but then how do I know if I am creating an object or updating (by whether it is transient if the Id is set or not?). How do I know if new images have been added and which to update or remove? I think the problem I am having is I call create pass a news aggregate to a Repository and create it, I could then get the aggregate back from the domain populated via the entities with EF and then add an image, when I pass the news aggregate back how do I know what has changed in order to create/update data?
Where should the customer go, should it be on the news aggregate object as an AddCustomer method, should there be a CustomerAggregate which has an AddNews method and with both of these options how to persist?
Many thanks for any insight, I've been reading around and looking at sample projects which demonstrate the concept but don't seem to fully explain best ways to achieve this.
First: DDD does not suggest you any specific architecture. I've used many different architectures with DDD and you should use what's good for the task. Obviously, if you think in a data driven way, you will encounter many problems with DDD.
DDD is a methodology designed to cope with complex business rules. You should not use it if your application value is in technological asset (as being in the cloud, exposing web services or some nice html5/mobile UI), but in the complexity of the business that it handles.
You should not use DDD for simple business rules. The rule of thumbs is: if you don't need a domain expert to understand the business, you don't need DDD at all.
Then, to properly understand aggregates, you should read the Vernon's essay on the topic.
That essay explain that aggregates exist to ensure business invariants.
You should never use aggregates just to optimize db access.
1) It depends on what capacity. There is a rule stating that aggregates can only reference other aggregates directly - not entities or value objects contained in other aggregates. This is to enforce aggregates as consistency boundaries - they fully encapsulate what they "aggregate". There should be a repository per aggregate. The presentation layer, and any outer layer, can require references to aggregates in two general capacities - for display purposes or for behavioral purposes. An aggregate shouldn't concern itself too much with how it will be displayed because queries can be implemented using a different model better suited for the task - a read-model. Instead, the aggregate should focus on behavior. And yes, in cases where the presentation layer wishes to execute a behavior on an aggregate it should reference the aggregate by its identity. Better yet, create an application service to encapsulate the domain layer and expose the behaviors as a simple facade.
Also, an aggregate is not a single class but usually a set of classes clustered around an aggregate root which is an entity. You don't necessarily need a separate class to represent the aggregate, it could just be the root entity.
2) For persistence, it seems you're using EF which should handle all change tracking for you. It should keep track of which objects are persistent or which are transient. ORMs such as NHibernate also do this.
2.1) This depends on whether Customer is itself an aggregate. If so, then News should reference Customer by ID only. Moreover, it may be that a customer is required for a news entity in which case a customer ID should be passed to the constructor of the News entity. If it is not required, then there is a behavior which associated a customer with a news entity. Consider this from the domain perspective - what is the meaning of associating a customer with a news entity? Try to move away from thinking in a technical, CRUD manner such as AddCustomer and think more in terms of the surrounding business intent.
As pointed out by Giacomo Tesio, DDD shows its value in domains with some complexity in business logic. If all your behaviors can be mapped to CRUD then leave it CRUD. Otherwise, look for behaviors in your domain instead of focusing on the data. Your entities and value objects should expose behaviors and hide state as much as possible. Do read and re-read the referenced article: Effetive Aggregate Design by Vaughn Vernon.
I have determined a relational model makes more sense for a particular collection in a database. The problem is, the domain model was originally started with an embedded model and there is a large amount of UI code that expects it to be in this form. Updating the database schema isn't an issue, but I'm curious if there is any easy way around remodeling the C# domain objects to a more old-fashioned relational model. I've started writing mappers (with AutoMapper) between version one and version two (see classes below), but it's getting messy really quick.
Below is some fictitious code that outlines a similar domain model.
// Existing
class MyClass
{
List<Event> Events { get; set; }
List<Movie> Movies { get; set; }
}
// How it should have been modeled
class MyClass
{
List<int> Events { get; set; } // Stores Event IDs
List<int> Movies { get; set; } // Stores Movie IDs
}
The database will have to be normalized.
If I have to remodel the domain model, that's fine; I just want to feel comfortable I've exhausted other possibilities that might save time. Is there an easy solution to this problem I'm overlooking?
If the only purpose of your restructuring is the relational database I'd advise you to look into O/R mapping. An O/R mapper, like NHibernate or the Entity Framework, should be able to map your existing embedded model to a relational database. Using an O/R mapper can take away the need of remodeling your domain.
Given the specific problem, it seemed the only two options I could justify were the two I mentioned in my initial post (map the data manually or change my domain object). Ultimately, for me, the path of least resistance was to map the data manually. I appreciate the suggestion by pjvds, but I couldn't justify switching to a new ORM at this stage of the project considering so many other things work better with the C# MongoDB driver and also considering a mapper isn't necessary for the other portions of our database.