Note on mixing constructor and object initialization syntax with EF Core entity classes
I made a small realization today about a different way to instantiate EF Core entities compared to what I’ve been doing. In the past when defining constructor methods for my EF Core entity classes, I encountered some problems with EF Core throwing errors with the constructor not being suitable, which made me avoid defining constructors and instead just use object initialization syntax everywhere like so:
for this entity class:
or
for
This works fine but it is a more verbose syntax compared to using a constructor in the usual way:
with the entities now being:
and
This is using the primary constructor syntax, and the required keyword on properties was removed as I found it wasn’t satisfied when using constructor parameters like this (it is satisfied using object initialization syntax).
This was working for me today while writing unit tests, but on actually dotnet runing the application, I got the same kind of EF Core errors on startup that had steered me away from using constructors before. Here is some of the output:
Unhandled exception. System.InvalidOperationException: No suitable constructor was found for entity type 'RecipeIngredient'. The following constructors had parameters that could not be bound to properties of the entity type:
Cannot bind 'quantity' in 'RecipeIngredient(string userId, string recipeId, string ingredientId, Quantity quantity)'
Note that only mapped properties can be bound to constructor parameters. Navigations to related entities, including references to owned types, cannot be bound.
And so the realization I had is that a better approach is to mix the constructor initialization with object initialization syntax:
This results in a less verbose syntax than using only object initialization syntax:
and the required keyword can be applied to the properties being set with object initialization syntax as well.
So this is the approach I am going to use: properties with value and string types will be set through a constructor, and required properties, reference navigations, enum types like UnitType above, and any others that EF Core does not like in the constructor will be set with object initialization syntax.