简体   繁体   中英

Code First Configuration Error

I'm trying to model a simple QA application using code first for learning purposes. Users should be able to ask questions, answer questions and write comments for both questions and answers. Here is my model classes:

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }

    public string UserName { get; set; }

    public DateTime? BirthDate { get; set; }

    public ICollection<Gym> Gyms { get; set; }
}

[Table("Question")]
public class Question
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int QuestionId { get; set; }

    public int UserProfileId { get; set; }

    [ForeignKey("UserProfileId")]
    public UserProfile UserProfile { get; set; }

    public string Header { get; set; }

    public string Content { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime CreateDate { get; set; }

    public ICollection<Answer> Answers { get; set; }

    public ICollection<QuestionComment> QuestionComments { get; set; }
}

[Table("QuestionComment")]
public class QuestionComment
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int QuestionCommentId { get; set; }

    public int UserProfileId { get; set; }

    [ForeignKey("UserProfileId")]
    public UserProfile UserProfile { get; set; }

    public int QuestionId { get; set; }

    [ForeignKey("QuestionId")]
    public Question Question { get; set; }

    [Column("Content", TypeName = "ntext")]
    public string Content { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime CreateDate { get; set; }
}

[Table("Answer")]
public class Answer
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int AnswerId { get; set; }

    public int UserProfileId { get; set; }

    [ForeignKey("UserProfileId")]
    public UserProfile UserProfile { get; set; }

    public int QuestionId { get; set; }

    [ForeignKey("QuestionId")]
    public Question Question { get; set; }

    [Column("Content", TypeName="ntext")]
    public string Content { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime CreateDate { get; set; }

    public IList<AnswerComment> AnswerComments { get; set; }
}

[Table("AnswerComment")]
public class AnswerComment
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int AnswerCommentId { get; set; }

    public int UserProfileId { get; set; }

    [ForeignKey("UserProfileId")]
    public UserProfile UserProfile { get; set; }

    public int AnswerId { get; set; }

    [ForeignKey("AnswerId")]
    public Answer Answer { get; set; }

    [Column("Content", TypeName = "ntext")]
    public string Content { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public DateTime CreateDate { get; set; }
}

And here is my db context class:

public class TestDbContext : DbContext
{
    public TestDbContext()
        : base("DefaultConnection")
    {
    }

    public DbSet<UserProfile> UserProfiles { get; set; }
    public DbSet<Question> Questions { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // After update
        modelBuilder.Entity<UserProfile>()
            .HasMany(p => p.Questions)
            .WithRequired()
            .HasForeignKey(c => c.UserProfileId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<UserProfile>()
            .HasMany(p => p.Answers)
            .WithRequired()
            .HasForeignKey(c => c.UserProfileId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<UserProfile>()
            .HasMany(p => p.AnswerComments)
            .WithRequired()
            .HasForeignKey(c => c.UserProfileId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<UserProfile>()
            .HasMany(p => p.QuestionComments)
            .WithRequired()
            .HasForeignKey(c => c.UserProfileId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Question>()
            .HasMany(p => p.Answers)
            .WithRequired()
            .HasForeignKey(c => c.QuestionId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Question>()
            .HasMany(p => p.QuestionComments)
            .WithRequired()
            .HasForeignKey(c => c.QuestionId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Answer>()
            .HasMany(p => p.AnswerComments)
            .WithRequired()
            .HasForeignKey(c => c.AnswerId)
            .WillCascadeOnDelete(false);
        // After update
    }
}

I'm getting the following error when creating db using the above declarations:

Introducing FOREIGN KEY constraint 'AnswerComment_UserProfile' on table 'AnswerComment' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.\\r\\nCould not create constraint. See previous errors.

What do I have to do to fix this?

Thanks in advance,

You have a table A that contains a FK to another table B. In the same time table A contains a FK to table C. Now, both tables B and C contains FKs to table D.

If all FKs are defined as delete cascade a record in table C can be deleted twice. This is not a logic problem, but SQL Server does not support this option.

To avoid this problem set on delete no action.

Try adding this to your UserProfile entity:

public virtual ICollection<AnswerComment> AnswerComments { get; set; }

And then add this to your modelBuilder , this should get rid off the error in your question, and you will probably have to do this for QuestionComment , Question , and Answer :

modelBuilder.Entity<AnswerComment>()
            .HasRequired(u => u.UserProfile)
            .WithMany(a => a.AnswerComments)
            .WillCascadeOnDelete(false);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM