Search code examples
c#database-designef-code-first

EF code first - Cycles or multiple cascade paths


I'm making a voting system. A Poll can have any number of PollOptions. A Vote can be blank (null on PollOptionId).

My models:

public class Poll
{
    public Guid Id { get; set; }
    public List<PollOption> Options { get; set; }
    // Some more properties.
}

public class PollOption
{
    public Guid Id { get; set; }
    public Guid PollId { get; set; }
    public Poll Poll { get; set; }
    public List<Vote> Votes { get; set; }
    // Some more properties.
}

public class Vote
{
    public Guid Id { get; set; }
    public Guid PollId { get; set; } // Needed for blank votes
    public Poll Poll { get; set; }
    public Guid? PollOptionId { get; set; } // Null if blank vote
    public PollOption Option { get; set; }
    // Some more properties.
}

Upon migration, I am faced with the error message

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

I can see the cycle, but I'm not sure how I could make my models any different for my purpose.

Could the design be changed to avoid the need to add a ON DELETE NO ACTION in modelBuilder?

If not, how would I do it?

My attempt:

modelBuilder.Entity<Vote>()
    .HasOne(p => p.Poll)
    .WithMany(o => o.Options)
    .OnDelete(DeleteBehavior.Restrict);

... which of course is not working, because PollOption != Vote.


Solution

  • Try to add Votes to Poll

    public class Poll
    {
        public Guid Id { get; set; }
        public virtual List<PollOption> Options { get; set; }
        public virtual List<Vote> Votes{ get; set; } 
        // Some more properties.
    }
    

    and maybe it would be usefull to make PollId nullable too

    public class Vote
    {
        public Guid Id { get; set; }
        .....
        public Guid? PollId { get; set; } 
        public virtual Poll Poll { get; set; }
        .....
    }