EF Core使用Fluent Api时出现复合键错误。

11

所以我在Entity Framework Core中有以下类。 我正在尝试进行首次代码迁移,但无论如何都无法弄清楚如何使这个流畅的API工作。

public class Participants
{
    public Activity Activity { get; set; } //Class with Id and Name of Activity
    public ApplicationUser Participant { get; set; } 

    [Key]
    [Column(Order = 1)]
    public int ActivityId { get; set; }


    [Key]
    [Column(Order = 2)]
    public string ParticipantId { get; set; }
}

在 EF6 中,我能够在 OnModelCreating 中这样做并使其正常工作。

 modelBuilder.Entity<Attendance>()
            .HasRequired(a => a.Activity)
            .WithMany()
            .WillCascadeOnDelete(false);

但在EF Core中,我得到了以下错误信息:

"实体类型'Participants'使用数据注释定义了复合主键。要设置复合主键,请使用流畅API。"

我已经尝试过使用

modelBuilder.Entity<Participants>().HasKey(p => new {p.Activity, p.Participant});

但是,这只会导致

在表“Participants”上引入FOREIGN KEY约束“FK_Participants_AspNetUsers_ParticipantId”可能会导致循环或多重级联路径。请指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。

如果有更好的方法来完成整个事情,我很乐意听取建议。如果您订阅了Pluralsight,我基本上正在尝试让Mosh Hamedani的“成为全栈开发人员”在EF Core中工作。该示例位于“13-full-stack-fundamentals”文件夹中。

更新:还尝试过

        modelBuilder.Entity<Participants>()
            .HasOne(p => p.Activity)
            .WithMany()
            .OnDelete(DeleteBehavior.Cascade);

仍然存在

"实体类型'参与者'已经在数据注释中定义了组合主键。要设置组合主键,请使用流畅API。"

更新2: 在尝试Roy的建议后,我得到了以下结果

在表“参与者”上引入外键约束“FK_Participants_AspNetUsers_ParticipantId”可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他外键约束。

更新3: 在迁移中

我删除了OneDelete:ReferntialAction.Cascade之一,然后它就起作用了。我将其从FK_Participants_AspNetUsers_ParticipantId中删除了。

我也在OnModelCreating中进行了更改。

        modelBuilder.Entity<Participants>()
            .HasKey(p => new { p.ActivityId, p.ParticipantId });
        base.OnModelCreating(modelBuilder);

        //Added this ( Not sure if it's needed if anyone knows let me know) 
        modelBuilder.Entity<Participants>()
            .HasOne(p => p.Activity)
            .WithMany()
            .OnDelete(DeleteBehavior.Cascade);

如果您以类似于modelBuilder.Entity<Attendance>().HasRequired(a => a.Activity).WithMany().WillCascadeOnDelete(false)的方式定义参与者和应用程序用户(Participant)之间的关系,会发生什么? - DevilSuichiro
更新以显示我尝试过的其他内容。 - vgwizardx
你可以分享“Activity”类型吗?你确定你没有引入循环路径吗?如果是这种情况,那么你不需要从迁移中删除任何内容。 - Smit
1个回答

18

你想要做的是在EFCore中创建一个Activity和Participant之间略有不同的关系。

为此,您需要在modelbuilder中引用ForeignKey属性而不是NavigationProperties,如下所示:

    modelBuilder.Entity<Participants>()
        .HasKey(p => new { p.ActivityId , p.ParticipantId });

@vgwizardx,我没看懂你的更新,你的更改修复了问题吗? - Roy Sanchez
是的,他们修复了我进行更改后发生的问题。我猜迁移过程中会创建双重级联路径。因此,您必须删除其中一个级联路径才能使事情完全正常工作。 - vgwizardx
1
虽然这个答案可能解决了问题,但是推理是错误的。在EF Core中,不允许使用数据注释来定义复合PK,并且必须使用流畅的API进行指定。这是无论任何导航或关系都是正确的。在上面的代码中,即使没有任何导航,它仍然会为复合PK抛出异常。 - Smit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接