【问题标题】:EF Core 3.1 DeleteBehavior.SetNull with Optional Relationship fires Constraint Exception具有可选关系的 EF Core 3.1 DeleteBehavior.SetNull 触发约束异常
【发布时间】:2021-02-25 02:53:42
【问题描述】:

我使用的是 EF Core 3.1 DB 首先,尝试将 DeleteBehavior.SetNull 设置为可选关系,但我仍然在 SaveChanges 上遇到异常。

实体是:Patient,它在名为Address 的字段中与Address 具有可空的关系。 实体是由这样的脚手架-DbContext cmd生成的(我删除了与问题无关的属性):

 public partial class Address
    {
        public Address()
        {
            Patient = new HashSet<Patient>();
        }

        public int Id { get; set; }
        ...

        public virtual ICollection<Patient> Patient { get; set; }
    }

和患者类别:

public partial class Patient
    {
        public int Code { get; set; }          
        public int? Address { get; set; }
        ...

        public virtual Address AddressNavigation { get; set; }
    }

OnModelCreating 函数中,我有以下代码:

modelBuilder.Entity<Patient>(entity =>
        {
            ...

        entity.HasOne(d => d.AddressNavigation)
            .WithMany(p => p.Patient)
            .HasForeignKey(d => d.Address)
            .HasConstraintName("FK__Patient__Address__2F10007B")
            .OnDelete(DeleteBehavior.SetNull);
    });

当我尝试删除地址时,使用以下代码行:

using (ClinicContext ctx = new ClinicContext())
{
    var address = ctx.Address.Find(addressId);
    ctx.Remove(address);
    ctx.SaveChanges();
}

我得到以下异常:

DELETE 语句与 REFERENCE 约束冲突 “FK__Patient__Address__2F10007B”。数据库发生冲突 “C:\USERS\USER\SOURCE\REPOS\CLINIC\DB\CLINIC.MDF”,表 “dbo.Patient”,“地址”列。声明已终止

我在这里错过了什么?

【问题讨论】:

  • 如果您首先使用 DB,那么除非您迁移数据库,否则 .OnDelete() 行为不会产生任何影响。我怀疑您数据库中的约束FK__Patient__Address__2F10007B 不可为空。
  • 这是创建表的脚本的相关部分: CREATE TABLE [dbo].[Patient] ( [Code] INT IDENTITY (1, 1) NOT NULL, [Id] VARCHAR (9 ) NOT NULL, [Address] INT NULL, PRIMARY KEY CLUSTERED ([Code] ASC), FOREIGN KEY ([Address]) REFERENCES [dbo].[Address] ([Id]) );
  • 是的,您需要将删除集 null 添加到您的表创建查询中
  • 恕我直言,在Patient 中同时拥有一个类型和一个名为Address 的属性非常令人困惑。我会调用可空的 int AddressId 左右

标签: c# asp.net-core entity-framework-core ef-fluent-api cascading-deletes


【解决方案1】:

正如@Jerry 所说,由于您使用的是 DB First,所以在您执行 scaffold-DbContext commond 之后,在生成的 DbContext 中添加 DeleteBehavior.SetNull 将不会影响您的数据库。

你最好用下面的语句重新创建你的表:

CREATE TABLE [dbo].[Patient] (
    [Code]    INT         IDENTITY (1, 1) NOT NULL,
    [Id]      VARCHAR (9) NOT NULL,
    [Address] INT         NULL,
    PRIMARY KEY CLUSTERED ([Code] ASC),
    FOREIGN KEY ([Address]) REFERENCES [dbo].[Address] ([Id]) ON DELETE SET NULL
);

【讨论】:

  • 谢谢你,@mj1313,这对我有用!我不知道SQL中的表本身有这样的定义,而且正如你和@Jerry所说,我不知道使用DB First,用OnModelCreating函数编写的流畅API对数据库端。
猜你喜欢
  • 1970-01-01
  • 2021-01-21
  • 1970-01-01
  • 1970-01-01
  • 2013-12-20
  • 1970-01-01
  • 1970-01-01
  • 2020-03-10
  • 2017-11-17
相关资源
最近更新 更多