Current Limitations of Entity Framework Core 8
Update: updated on 31/07/2024 for EF Core 8
Introduction
Although EF Core seems to be the most popular ORM in the .NET world in these days – and I for sure won’t contradict it –, there is still some functionality missing, specially if we compare it with other ORMs that also exist, NHibernate coming obviously to my mind. This post is a reflection about that, it is in no way a comparison with other ORMs, in particular, NHibernate, it’s more a wish list for EF Core. I still follow and love NHibernate, and it’s still, in many ways, somewhat ahead of EF Core, but that’s not what I’ll be writing about. I had a list here, and I recently updated it.
Primary Key Generation
EF Core currently only supports the following primary key generation strategies:
-
Identity/autoincrement (on databases that support it)
-
GUID/uniqueidentifier (on databases that support it)
-
Sequence-based (on databases that support it)
-
HiLo (SQL Server only)
-
Manually assigned
For GUIDs, EF Core automatically generates, on the client-side, a new value before inserting, which is nice.
HiLo is a great pattern for generating primary keys, but, unfortunately, the way Microsoft implemented it, resorting to database sequences, makes it database-specific – currently, SQL Server only. If it were implemented with just standard DML commands, it could be made database-agnostic, for the benefit of all.
I dare say that EF Core is slightly biased towards SQL Server and, even more, that most SQL Server folks are used to having IDENTITY as their default primary key generation strategy. While this is fine, it does prevent batch insertions, because it requires obtaining the generated primary key after each inser (SELECT SCOPE_IDENTITY()). If we have a client-generated primary key, batch insertion is possible, which can be a great benefit.
I’d like to have a truly extensible primary key generation mechanism on EF Core. Maybe something for the future.
Collection Types
Currently, EF Core supports:
- Collections of entities
- Collections of owned types
- Collections of primitive types
All can be lazy loaded, in which case, you need to declare them as ICollection<T> or IList<T>, but, you don’t have semantic collections such as sets or bags, or indexed collections such as lists or maps.
Table Inheritance Patterns
There are three canonical table inheritance patterns:
Currently, all of them are fully supported.
Mapping Entities to Views or SQL
In EF Core it is called keyless entity types mapping, and it is supported now.
Expression Columns
It is now possible to map a property to a SQL expression.
Expressions for CUD Operations
Another useful operation, the ability to use raw SQL – which could even be a stored procedure call – for Create, Update, and Delete (CUD) operations is already supported.
Strongly Typed DML Operations
Also known as bulk updates and deletes, they're here too.
Lifecycle Events
All of the typical lifecycle events are now implemented.
Interceptors
Here too.
Entity and Table Splitting
Both entity and table splitting are now supported as well.
Owned Types
For properties and collections, also here.
Value Converters
Value converters for types have been around for some time now.
Conclusion
In conclusion, we can see that pretty much anything that has been missing for a while is now implemented! Some features are still missing or partially implemented (I would place custom key generation on top), but the future looks bright for EF Core!