【问题标题】:EF Core HasOptional WithOptionalDependentEF Core HasOptional WithOptionalDependent
【发布时间】:2022-02-16 16:08:47
【问题描述】:

我的数据库中有以下表格:

Product                                 ResourceAssociation
-------                                 ------------------
Name                          /-------> Id
ResourceAssociation_Id ------/         SomeProperty

所以 Product 有一个 ResourceAssociation_Id,它是 ResourceAssociation 表的 FK。

这是一个遗留应用程序,它的 Entity Framework 6 映射包含这段代码:

HasOptional(t => t.ResourceAssociation).WithOptionalDependent().WillCascadeOnDelete(true);

我希望将其移植到 EF Core。看来,EF Core 不再具有 HasOptional 了。我试过这个:

builder.HasOne(t => t.ResourceAssociation)
    .WithOne().HasForeignKey("ResourceAssociation_Id")
    .IsRequired(false)
    .OnDelete(DeleteBehavior.Cascade);

我还尝试将WithOne 替换为WithMany。但它不起作用。

当我尝试创建没有 ResourceAssociation 的新产品时(因为它不是必需的),EF Core 仍然告诉我我的 ModelState 无效,因为 ResourceAssociation 为空。

我无法在 WithOne 中指定属性(例如 WithOne(x => x.Product)),因为 ResourceAssociation 是一个也将用于其他表的表(例如 Brand 也有一个指向该表的 ResourceAssociation_Id 列)。

这种设置在 EF Core 中是否可行?或者我是否必须将不同的导航属性添加到我的 ResourceAssociation 类(即产品、品牌……)?

【问题讨论】:

    标签: c# entity-framework-core


    【解决方案1】:

    在 EF Core 中,HasOne / WithOne(即使具有导航属性)不足以确定一对一关系中哪个是主体,哪个是依赖实体(对于一对多一个总是主要的,许多是依赖的,对于多对多,没有主要/依赖)。

    因此,HasForeignKey / HasPrincipalKey通用类型参数对于分别确定依赖/主体实体是必需的。这实际上在Other Relationship Patterns - One-to-one EF Core 文档主题中进行了解释:

    在使用 Fluent API 配置关系时,您使用 HasOneWithOne 方法。

    在配置外键时,您需要指定依赖实体类型 - 请注意下面列表中提供给 HasForeignKey 的通用参数。在一对多关系中,很明显具有引用导航的实体是依赖实体,而具有集合的实体是主体。但这不是一对一的关系——因此需要明确定义它。

    因此,您需要在这里指定 Product 作为关系的依赖项,以及 FK 属性/列名:

    builder.HasOne(t => t.ResourceAssociation)
        .WithOne() // ok, no navigation
        .HasForeignKey<Product>("ResourceAssociation_Id") // FK name in the dependent
        //               ^^^ the dependent entity of the relationship
        .IsRequired(false)
        .OnDelete(DeleteBehavior.Cascade);
    

    【讨论】:

    • 谢谢。我还必须使属性可以为空(在我声明属性的类型后面添加一个问号)。
    • 对我之前评论的更正:我已将模型移至一个新项目,其中不可为空的引用类型设置为“启用”。删除它(默认 = 禁用)会使 EF Core 在必需/可选属性方面以旧方式运行。
    • 是的,这是 EF Core 中 NRT 支持的一部分。
    猜你喜欢
    • 2015-11-25
    • 1970-01-01
    • 2013-09-11
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 2020-03-29
    • 2021-09-18
    • 2020-12-08
    相关资源
    最近更新 更多