【问题标题】:Entity Framework Core code first - 0..1 to many relationship and cascade deleteEntity Framework Core 代码优先 - 0..1 对多关系和级联删除
【发布时间】:2016-06-30 00:16:36
【问题描述】:

我正在尝试创建一个由 Entity Framework Core 支持的评论系统,其中多个不同类型的实体可以附加 cmets。

这些是我的实体。 (在实际应用中,总共有大约 7 个关系不同,但通常看起来是这样的)

public class Comment : IEntityBase
{
    public int Id { get; set; }

    public int? FreezerId{ get; set; }
    public Freezer Freezer { get; set; }
    public int? BoxId{ get; set; }
    public Box Box{ get; set; }
    public string Author { get; set; }
    public DateTime CreatedAt { get; set; }
    public string Content { get; set; }
}

public class Freezer: IEntityBase
{
    public int Id { get; set; }

    public string Name { get; set; }
    public string Location { get; set; }
    public ICollection<Box> Boxes{ get; set; }
    public ICollection<Comment> Comments { get; set; }
}

public class Box: IEntityBase
{
    public int Id { get; set; }

    public Freezer Freezer{get; set;}
    public int FreezerId{get; set;}
    public string Data{ get; set; }
    public ICollection<Comment> Comments { get; set; }
}

我希望将 Comment 实体附加到一个 Freezer 或一个 Box,但不能同时附加到两者。

我在fluent API中定义了如下关系:

 builder.Entity<Box>(boxBuilder=>
        {
            boxBuilder.HasOne(box=> box.Freezer)
                .WithMany(freezer => freezer.boxes)
                .HasForeignKey(box => box.FreezerId)
                .IsRequired()
                .OnDelete(DeleteBehavior.Cascade);

            boxBuilder.HasMany(box => box.Comments)
                .WithOne(comment => comment.Box)
                .HasForeignKey(comment => comment.BoxId)
                .OnDelete(DeleteBehavior.Cascade);
        });

 builder.Entity<Freezer>(freezerBuilder =>
        {
            freezerBuilder.HasMany(freezer=> freezer.Comments)
                .WithOne(comment => comment.Freezer)
                .HasForeignKey(comment => comment.FreezerId)
                .OnDelete(DeleteBehavior.Cascade);
        });

当我尝试将数据库更新为此模型时,我收到以下错误:

System.Data.SqlClient.SqlException: Introducing FOREIGN KEY constraint 'FK_Comment_Boxes_BoxId' on table 'Comment' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.

我认为错误来自 Box 和 Comment 类中的 Freezer 属性不是可选的,这将使其成为 1 对多 关系而不是 >0..1 到许多 关系,这是我想要的。

对于 Entity Framework 6,我只会使用 .HasOptional() 方法,但这在 Entity Framework Core 中不存在

我认为解决此问题的一种方法是仅将 Comment 类子类化,并为每个可以评论的实体创建一个唯一的评论类,然后将外键和引用属性移至该子类。

但感觉我不应该这样做。

【问题讨论】:

  • 我的回答解决了你的问题吗?

标签: c# .net entity-framework entity-framework-core


【解决方案1】:

你必须禁用级联删除(DeleteBehavior.Restrict) 然后它会为你工作:

 modelBuilder.Entity<Box>(boxBuilder =>
        {
          boxBuilder.HasOne(box => box.Freezer)
              .WithMany(freezer => freezer.Boxes)
              .HasForeignKey(box => box.FreezerId)
              .IsRequired()
              .OnDelete(DeleteBehavior.Cascade);

          boxBuilder.HasMany(box => box.Comments)
              .WithOne(comment => comment.Box)
              .HasForeignKey(comment => comment.BoxId)
              .OnDelete(DeleteBehavior.Restrict);
        });

        modelBuilder.Entity<Freezer>(freezerBuilder =>
        {
          freezerBuilder.HasMany(freezer => freezer.Comments)
              .WithOne(comment => comment.Freezer)
              .HasForeignKey(comment => comment.FreezerId)
              .OnDelete(DeleteBehavior.Restrict);
        });
        base.OnModelCreating(modelBuilder);
      }

用法:

using (var myConext = new MyDbContext())
      {
        myConext.Database.EnsureCreated();
        myConext.Boxes.Add(new Box() {Freezer =  new Freezer()});
        myConext.SaveChanges();
      }

【讨论】:

    猜你喜欢
    • 2017-06-02
    • 2016-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 2014-11-24
    • 2020-04-29
    • 1970-01-01
    相关资源
    最近更新 更多