-
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
How to correctly configure a composite primary key with HasDefault() for Sqlite? #27299
Comments
Note for triage: this appears to be related to the FK property being used in two relationships. It is both part of a composite FK, and also an FK on it's own. This means we don't detect properly that it is marked as generated and hence doesn't need to have an explicit value set. @Metritutus As a workaround, can you explicitly set the value, rather than relying on it being set by the default constraint? |
If I explicitly set the value when creating the model instance, eg: var somethingOfCategoryB = new SomethingOfCategoryB() { CategoryId = 2, SomethingId = newSomething.Id, Name = "Whatever" }; Or if I set it in the model class itself like this: public int CategoryId { get; set; } = 2; Then yes, that does work, although I had hoped to avoid this and be able to do this with shadow properties, as my goal in this was to avoid having the property existing in the model, so that it cannot be manually set, read, etc. Am I correct then that this isn't going to be possible until this issue is resolved? It looks like I may have to make do with a getter-only model property for the time being if that is the case. I have also tried using EDIT: The EDIT2: Looks like I can achieve what I want by overriding The workaround: public override int SaveChanges()
{
foreach (EntityEntry entityEntry in ChangeTracker.Entries().Where(ee => ee.State == EntityState.Added))
{
if (entityEntry.Entity is SomethingOfCategoryA)
{
entityEntry.CurrentValues["CategoryId"] = Models.Categories.A;
}
}
return base.SaveChanges();
} |
@Metritutus That workaround looks good to me. |
I am attempting to configure a composite primary key for a table, where one of key fields has a default value specified using
HasDefault()
. This key field with a default value is never intended to be manually set by code, so I wanted to create it as a shadow property.The configuration code I have written successfully generates migration scripts which run without error. If run
SELECT * FROM pragma_table_info("SomethingOfCategoryA")
, the columns appear to be configured as I would expect.SomethingOfCategoryB
also looks as I would expect (ie identical toSomethingOfCategoryA
aside from the default value).In addition, if I manually run SQL to insert records into either of the two tables, it all works as expected, making use of the default value on the column, etc.
However, if I try to insert a record using EF Core for
SomethingOfCategoryA
orSomethingOfCategoryB
, anInvalidOperationException
like the following is thrown:I was initially attempting to achieve what I wanted using shadow properties (as seen for the configuration of
SomethingOfCategoryA
), and was unsure if this error was the result of those efforts. However attempting this using properties in the model itself (as seen for the configuration ofSomethingOfCategoryB
) has the same result.I am unsure what I am doing wrong.
In researching this I happened upon this issue, although I am unsure if this is the same problem, and in any case that issue is marked as fixed and the advice there is to open a new issue with a small project that reproduces the issue for investigative purposes.
Stack trace
The code
The code for the test project that demonstrates this issue can be found here.
Simply run the project observe the thrown exception.
Provider and version information
EF Core version: 5.0.13
Database provider: Microsoft.EntityFrameworkCore.Sqlite
Target framework: .NET Core 3.1
Operating system: Windows 10 Version 21H2 (OS Build 19044.1415)
IDE: Visual Studio 2022 17.0.2
The text was updated successfully, but these errors were encountered: