实体框架核心ForeignKeyAttribute两侧

Har*_*uck 4 .net c# database entity-framework entity-framework-core

我有一个使用 Entity Framework Core 的应用程序,在我的上下文中具有不同的实体,但其中有两个实体需要一对零或一的关系。我这样做并确保验证的方法是执行如下操作:

public class PurchasedPackage
{
    public int Id { get; set; }

    ...

    [ForeignKey(nameof(PurchasedPackageModifier))]
    public int? PurchasedPackageModifierId { get; set; }

    public virtual PurchasedPackageModifier PurchasedPackageModifier { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

public class PurchasedPackageModifier
{
    public int Id { get; set; }

    ...

    [Required]
    [ForeignKey(nameof(PurchasedPackage))]
    public int PurchasedPackageId { get; set; }

    public virtual PurchasedPackage PurchasedPackage { get; set; }

    ...
}
Run Code Online (Sandbox Code Playgroud)

哪里PurchasedPackage是必需的,哪里PurchasedPackageModifier是可选的。通过在两侧指定ForeignKey属性,我试图确保保存到两个表的数据完整性,这样就没有人创建PurchasedPackage不存在的属性PurchasedPackageModifier,反之亦然。

虽然这按要求工作,但我在日志中收到警告,说明以下内容:

'PurchasedPackage.PurchasedPackageModifier' and 'PurchasedPackageModifier.PurchasedPackage' were separated into two relationships as ForeignKeyAttribute was specified on properties 'PurchasedPackageModifierId' and 'PurchasedPackageId' on both sides.
Run Code Online (Sandbox Code Playgroud)

'PurchasedPackageModifier.PurchasedPackage' and 'PurchasedPackage.PurchasedPackageModifier' were separated into two relationships as ForeignKeyAttribute was specified on properties 'PurchasedPackageId' and 'PurchasedPackageModifierId' on both sides.
Run Code Online (Sandbox Code Playgroud)

我的问题是:我这样做是否正确,在这种特殊情况下我应该忽略这些警告还是有更好的方法来实现相同的验证/完整性行为?

use*_*495 9

你\xe2\x80\x99正在以正确的方式做这件事。根据微软的说法,显示警告的原因是因为大多数时候将外键放在相互引用的两个表上是错误的,除非您正在创建一对一的关系。以下是 Microsoft 实体框架工程经理的一句话:

\n
\n

该警告基本上是说,以这种方式使用ForeignKeyAttribute 会创建两个关系,因为人们错误地执行此操作并不想创建两个关系的情况并不少见。

\n

https://github.com/dotnet/efcore/issues/11756#issuecomment-383640800

\n
\n

DbContextOptionsBuilder.ConfigureWarnings()要抑制警告,请在班级中调用DbContext

\n
using Microsoft.EntityFrameworkCore.Diagnostics;\n\npublic sealed class SampleDbContext : DbContext\n{\n    /* DbContext code... */\n    protected override void OnConfiguring(DbContextOptionsBuilder Builder)\n    {\n        Builder.ConfigureWarnings(delegate (WarningsConfigurationBuilder warnings)\n        {\n            // The following line will suppress the warning\n            // "\'Foo.Bar\' and \'Bar.Foo\' were separated into two relationships as\n            // ForeignKeyAttribute was specified on properties \'BarId\' and\n            // \'FooId\' on both sides."\n            warnings.Ignore(CoreEventId.ForeignKeyAttributesOnBothNavigationsWarning);\n        });\n    }\n    /* DbContext code... */\n}\n
Run Code Online (Sandbox Code Playgroud)\n