I have an application with Entity Framework Core with different entities in my context, but there are two of them that require a one-to-zero-or-one relation. My way of doing that and ensuring validation was to do something like the following:
public class PurchasedPackage
{
public int Id { get; set; }
...
[ForeignKey(nameof(PurchasedPackageModifier))]
public int? PurchasedPackageModifierId { get; set; }
public virtual PurchasedPackageModifier PurchasedPackageModifier { get; set; }
}
And
public class PurchasedPackageModifier
{
public int Id { get; set; }
...
[Required]
[ForeignKey(nameof(PurchasedPackage))]
public int PurchasedPackageId { get; set; }
public virtual PurchasedPackage PurchasedPackage { get; set; }
...
}
Where PurchasedPackage
is required and PurchasedPackageModifier
is optional. By specifying ForeignKey
attribute on both sides I'm trying to ensure data integrity across saves to both tables so nobody creates a PurchasedPackage
with a non-existent PurchasedPackageModifier
and vice versa.
While this works as required I'm getting warnings in my logs stating the following:
'PurchasedPackage.PurchasedPackageModifier' and 'PurchasedPackageModifier.PurchasedPackage' were separated into two relationships as ForeignKeyAttribute was specified on properties 'PurchasedPackageModifierId' and 'PurchasedPackageId' on both sides.
And
'PurchasedPackageModifier.PurchasedPackage' and 'PurchasedPackage.PurchasedPackageModifier' were separated into two relationships as ForeignKeyAttribute was specified on properties 'PurchasedPackageId' and 'PurchasedPackageModifierId' on both sides.
My question is: am I doing this right and should I ignore these warnings in this particular case or there is a better way of achieving same validation/integrity behavior?
You’re doing it the right way. According to Microsoft, the reason a warning is shown is because most of the time it's a mistake to put foreign keys on two tables that reference each other, unless of course you're creating a one-to-one relationship. Here's a quote from an Engineering Manager for Entity Framework at Microsoft:
The warning is basically saying that using ForeignKeyAttribute in this way creates two relationships because it is not uncommon for people to do this by mistake not intending it to create two relationships.
https://github.com/dotnet/efcore/issues/11756#issuecomment-383640800
To suppress the warning, make a call to DbContextOptionsBuilder.ConfigureWarnings()
in your DbContext
class:
using Microsoft.EntityFrameworkCore.Diagnostics;
public sealed class SampleDbContext : DbContext
{
/* DbContext code... */
protected override void OnConfiguring(DbContextOptionsBuilder Builder)
{
Builder.ConfigureWarnings(delegate (WarningsConfigurationBuilder warnings)
{
// The following line will suppress the warning
// "'Foo.Bar' and 'Bar.Foo' were separated into two relationships as
// ForeignKeyAttribute was specified on properties 'BarId' and
// 'FooId' on both sides."
warnings.Ignore(CoreEventId.ForeignKeyAttributesOnBothNavigationsWarning);
});
}
/* DbContext code... */
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With