-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Validate requiredness (nullability) in the in-memory database #10613
Comments
@vnvizitiu Several points on this:
|
Thanks for the quick reply. I looked through the mentioned issues. It was my understanding that the in-memory implementation was a way to help out with unit testing, personally, I kinda see it as an issue if the test behaves one way and the production behaves a different way. Also, I did not test this yet (but I will eventually when the domain grows), but if nullability is not checked, does this mean foreign key constraints do not apply as well? On a side note, please also consider the confusion with the documentation since this was also brought up there. |
@vnvizitiu The in-memory database is not a relational database and so it does not always have the semantics of a relational database, as described here: https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/ and here: https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/in-memory. If you need to test with relational semantics, then you may be better off using SQLite in-memory: https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/sqlite, but even then SQLite will likely behave differently than your production database server. In general, what you use for testing depends on how much your tests depend on actual database behavior. The only way to ensure the same behavior is to use the same database engine. |
Thanks for the info, sorry I couldn't respond earlier, was away |
I'm also interested in EF In Memory DB handling correctly the requiredness of fields like string, for unit (or not-so-unit)- testing purposes. I don't really understand what "up-for-grabs" tag means. Does it indicate that the enhancement will be grabbed in some near-future next version ? |
@lioobayoyo "up-for-grabs" means that we believe the fix for this issue is straightforward enough that somebody without deep knowledge of EF Core internals could likely create a pull request for it. In other words, it's a good first-time issue for somebody wanting to contribute to EF Core. |
Hello Arthur. |
@Saibamen I'm not sure what you are asking. Can you elaborate? |
Ok, let me write why we need in-memory testing. We do a database migration from EF6 to EF Core 5.0 and we want to write in-memory tests to check if our Context is compatible with old one (like checking if Validation Errors are correct - trying to add too long string and checking if Exception from HasMaxLength(50) is thrown). We can't do this because of this issue. We tried SQLite, but we failed at the DB configuration, because we have duplicated indexes (we can't change that, because we need to be compatible with old DB) - issue #14548 |
Hey @ajcvickers, can I take this one? I would add a public override int SaveChanges()
{
var entries = ChangeTracker.Entries()
.Where(e => e.State == EntityState.Modified || e.State == EntityState.Added)
.ToList();
foreach (var entry in entries)
{
var properties = entry.Metadata.GetProperties();
foreach(var property in properties)
{
var value = property.PropertyInfo.GetValue(entry.Entity);
if (!property.IsNullable && value == null)
{
throw new DbUpdateException("Required properties are missing");
}
}
}
return base.SaveChanges();
} For the exception message I would take an approach similar to how concurrency conflicts are handled today in the
|
@vnvizitiu Sorry for the slow response--I've been out for a bit. Yes, feel free to take this on. The approach you suggest seems reasonable. However, this will be a breaking change, so we may want to:
@dotnet/efteam Any thoughts on the breaking nature of this? |
Considering that the main use of InMemory is for testing code that otherwise uses relational databases, I'd vote for enabling by default but possibly providing an opt-out knob. |
Thank you, this makes sense @ajcvickers and @roji! I will create a PR in the next few days. |
Description
I created a model that has a name property which I tried setting as required from both the ModelBuilder and using annotations.
When inspecting the tracked changes it confirms that the property IsNullable == false, out of this 2 scenarios arise:
This was confirmed through an NUnit test (for the in-memory database) and in an ASP.NET Core 2 application (for the exception version)
Steps to reproduce
The following code is from the Unit Test
Expected Results
The SaveChanges() method should have thrown an exception since the model requirements were not fulfiled
Further technical details
EF Core version: 2.0.1
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10 Pro
IDE: Visual Studio 2017 15.5.2
Mentions
This issue was also mentioned in the documentation found here in the first and last comments.
The text was updated successfully, but these errors were encountered: