Nullable error with lazy loading in EF Core
EF Core is pretty strict about nullable reference types. I wrote about this before in the context of migrations, but it also affects loading of data from the database. If you try to load a null value into a non-nullable
string property, a
SqlNullValueException will be thrown:
System.Data.SqlTypes.SqlNullValueException: 'Data is Null. This method or property cannot be called on Null values.'
The error message could be more informative. If nothing else, it could at least give some indication which property or database field it refers to.
To make matters worse, the same error is thrown when you access a lazy loaded navigation property for the first time. It took me some time to figure out the reason when troubleshooting the error. At first, I thought that the foreign key column value was null. Only after noticing the
String type in the call stack, I started considering the properties in the lazy loaded object:
at Microsoft.Data.SqlClient.SqlBuffer.ThrowIfNull() at Microsoft.Data.SqlClient.SqlBuffer.get_String() at Microsoft.Data.SqlClient.SqlDataReader.GetString(Int32 i)
When I looked at the values in the database. I finally realized that there was a null value in a column mapped to a non-nullable
string property. Of course, this shouldn't happen when using the model-first approach with migrations, but it's much more likely when reverse engineering the model with scaffolding.
I created a sample project in which I incorrectly made a non-nullable model property that was mapped to a nullable database field to reproduce the exception. You can find the code in my GitHub repository.
In most cases, nullable reference types in .NET only result in compiler warnings and won't cause run time exceptions. That's not how EF Core works. If you enable nullable reference types for a project, you must make sure to always use a nullable type when the underlying value in the database can be null. If you fail to do that, you will encounter errors at run time.