多个级联路径错误 - 实体框架核心

时间:2017-03-06 19:49:17

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

我正在尝试使用Entity Framework Core设置一个新数据库但是在调用命令时遇到错误" Update-Database"说:

"Introducing FOREIGN KEY constraint 'FK_Answers_Users_UserId' on table 'Answers' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints."

我不打算从数据库中删除任何内容,但如果删除用户,我可以设置删除与用户相关的所有内容。

以下是我的模特:

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Username { get; set; }
    public string ImageUrl { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateModified { get; set; }
    public int AnswersFlagged { get; set; }
    public bool Status { get; set; }

    public IEnumerable<Dispute> Disputes { get; set; }
    public IEnumerable<Answer> Answers { get; set; }
}

public class Dispute
{
    public int Id { get; set; }
    public int UserId { get; set; }
    public int CategoryId { get; set; }
    public string Text { get; set; }
    public string OptionOneText { get; set; }
    public string OptionTwoText { get; set; }
    public string OptionThreeText { get; set; }
    public string OptionOneImageUrl { get; set; }
    public string OptionTwoImageUrl { get; set; }
    public string OptionThreeImageUrl { get; set; }
    public DateTime DateCreated { get; set; }
    public DateTime DateModified { get; set; }
    public bool Status { get; set; }

    public User User { get; set; }
    public Category Category { get; set; }
    public IEnumerable<Answer> Answers { get; set; }
}

public class Answer
{
    public int Id { get; set; }
    public int DisputeId { get; set; }
    public int UserId { get; set; }
    public int SelectedOption { get; set; }
    public string Comment { get; set; }
    public bool Flagged { get; set; }
    public DateTime DateCreated { get; set; }

    public Dispute Dispute { get; set; }
    public User User { get; set; }
}

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime DateCreated { get; set; }
    public bool Status { get; set; }

    public IEnumerable<Dispute> Disputes { get; set; }
}

public class DisputeCategory
{
    public int Id { get; set; }
    public int DisputeId { get; set; }
    public int CategoryId { get; set; }

    public Dispute Dispute { get; set; }
    public Category Category { get; set; }
}

我在DbContext中尝试了以下操作:

1)

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Answer>()
        .HasOne(p => p.User)
        .WithMany(b => b.Answers)
        .OnDelete(DeleteBehavior.Restrict);
}

2)

 protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
        modelBuilder.Entity<Answer>()
            .HasOne(p => p.User)
            .WithMany(b => b.Answers)
            .IsRequired(false);
 }

3)

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
    {
        relationship.DeleteBehavior = DeleteBehavior.Restrict;
    }
}

要正确设置此设置,我需要做什么?

1 个答案:

答案 0 :(得分:3)

我认为这可以在Answer实体中解决,将DisputeId更改为可以为空:

public class Answer
{
    public int Id { get; set; }
    public int? DisputeId { get; set; }
    //..

    public Dispute Dispute { get; set; }
    //..
}

以这种方式配置你的关系:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Answer>()
        .HasOne(p => p.User)
        .WithMany(b => b.Answers)
        .HasForeignKey(s =>s.UserId) ;

    modelBuilder.Entity<Answer>()
        .HasOne(p => p.Dispute)
        .WithMany(b => b.Answers)
        .HasForeignKey(s =>s.DisputeId) ;
}

convention可以选择第二种关系,因此可以解决您的问题。

来自EF core文档:

  

按照惯例,级联删除将设置为Cascade for required   关系和限制可选关系。级联意味着也会删除依赖实体。   限制意味着未加载到内存中的从属实体   将保持不变,必须手动删除或更新为   指向有效的主体实体。对于加载到的实体   在内存中,EF将尝试将外键属性设置为null。

     

如果您的实体类中有外键属性,那么   关系的必要性是根据是否确定   外键属性是必需的或可选的