如何删除与同一个表1:1关系的行?

时间:2018-05-12 21:40:01

标签: entity-framework entity-framework-core cascade one-to-one

我使用的是Entity Framework Core,我有一个表:

public class BlogComment
{
    public int Id { get; set; }
    public BlogPost Post { get; set; }
    [StringLength(100)]
    public string AuthorName { get; set; }
    [StringLength(254)]
    public string AuthorEmail { get; set; }
    public bool SendMailOnReply { get; set; }
    [StringLength(2000)]
    public string Content { get; set; }
    public DateTime CreatedTime { get; set; }
    public int? ReplyToId { get; set; }
    public BlogComment ReplyTo { get; set; }
}

由此,EFC生成下表:

CREATE TABLE [dbo].[BlogComment] (
    [Id]              INT             IDENTITY (1, 1) NOT NULL,
    [AuthorEmail]     NVARCHAR (254)  NULL,
    [AuthorName]      NVARCHAR (100)  NULL,
    [Content]         NVARCHAR (2000) NULL,
    [CreatedTime]     DATETIME2 (7)   NOT NULL,
    [PostId]          INT             NULL,
    [ReplyToId]       INT             NULL,
    [SendMailOnReply] BIT             NOT NULL,
    CONSTRAINT [PK_BlogComment] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_BlogComment_BlogPost_PostId] FOREIGN KEY ([PostId]) REFERENCES [dbo].[BlogPost] ([Id]),
    CONSTRAINT [FK_BlogComment_BlogComment_ReplyToId] FOREIGN KEY ([ReplyToId]) REFERENCES [dbo].[BlogComment] ([Id])
);
GO
CREATE NONCLUSTERED INDEX [IX_BlogComment_PostId]
    ON [dbo].[BlogComment]([PostId] ASC);
GO
CREATE UNIQUE NONCLUSTERED INDEX [IX_BlogComment_ReplyToId]
    ON [dbo].[BlogComment]([ReplyToId] ASC) WHERE ([ReplyToId] IS NOT NULL);

有些评论会作为回复发送给另一个,但不是全部。删除原始注释后,回复将成为正常注释。因此,在this tutorial之后,配置看起来是这样的:

modelBuilder.Entity<BlogComment>()
      .HasOne(p => p.ReplyTo)
      .WithOne()
      .HasForeignKey<BlogComment>(c => c.ReplyToId)
      .IsRequired(false)
      .OnDelete(DeleteBehavior.SetNull);

删除方法非常简单:

var comment = await context.BlogComment.Include(c => c.ReplyTo).SingleAsync(m => m.Id == id);
context.BlogComment.Remove(comment);
await context.SaveChangesAsync();

但我无法运行它,我收到错误:

  

System.Data.SqlClient.SqlException:DELETE语句与SAME TABLE REFERENCE约束“FK_BlogComment_BlogComment_ReplyToId”冲突。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我可以通过手动将ReplyTo设置为null来使其正常工作。我还在寻找更好的解决方案,或解释为什么需要它。它不是OnDelete(DeleteBehavior.SetNull)应该做的吗?

var comment = await context.BlogComment.Include(c => c.ReplyTo).SingleAsync(m => m.Id == id);
var reply = await context.BlogComment.SingleOrDefaultAsync(m => m.ReplyToId == id);
if (reply != null)
{
    reply.ReplyTo = null;
    reply.ReplyToId = null;
    context.Entry(reply).State = EntityState.Modified;
}
context.BlogComment.Remove(comment);

答案 1 :(得分:0)

对我来说,我必须Include()删除实体时需要“处理”的实体。 EF无法管理当前未跟踪的内容。

var breedToDelete = context.Breed
    .Include(x => x.Cats)
    .Single(x => x.Id == testBreedId);

context.Breed.Remove(breedToDelete);
context.SaveChanges();