1

I have three model classes:

  1. User.
  2. Entry.
  3. EntryLikes.

As follows:

public class User
{
    [Required]
    public int ID { get; set; }

    [Required]
    [DataType(DataType.Text)]
    public string Name { get; set; }
}
public class Entry
{
    [Required]
    public int ID { get; set; }

    public int UserID { get; set; }
    [ForeignKey("UserID")]
    public virtual User User { get; set; }
}
public class EntryLike
{
    [Required]
    public int ID { get; set; }

    [Required]
    public int UserID { get; set; }
    [ForeignKey("UserID")]
    public virtual User User { get; set; }

    [Required]
    public int EntityID { get; set; }
    [ForeignKey("EntityID")]
    public virtual Entry Entry { get; set; }
}

Upon execution I got following exception:

Introducing FOREIGN KEY constraint 'FK_dbo.EntryLikes_dbo.Entries_EntityID' on table 'EntryLikes' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint. See previous errors.

Mahmoud Gamal
  • 78,257
  • 17
  • 139
  • 164
Fahad
  • 25
  • 5

2 Answers2

0

Why do you have a foreign key relationship with User from EntryLike and from Entry? Given that you have a relationship between Entry and User on the Entry class, you don't need one on the EntryLike class as it can be inferred due to the relationship between EntryLike and Entry. Also, should the foreign key id property on EntryLike be called EntryID rather than EntityID?

EDIT: It's because you have multiple cascade paths to your User - one is Entry > User and the other is EntryLike > Entry > User. You will need to switch cascade delete off to stop this error from occurring. The links I put in the comment should get you on the right track.

levelnis
  • 7,665
  • 6
  • 37
  • 61
  • Thanks for giving time. Sorry for spelling mistake. Actually it is EntryID. Scenario is: A user can have many entries, and a user can like other users' entries (as we can like other facebook users' photos). EntryLikes model is used to track that likings. The UserID which we get from Entry composed in EntryLikes will be the UserID of the owner of that Entry, but we want to keep record of that users who are liking that entries. Hope i have better explained the scenario. – Fahad Dec 16 '12 at 13:40
  • OK, but as far as I can tell, you're not actually modelling the relationships the other way around. A User can have many Entries - that isn't being captured. You need a property like `public virtual IEnumerable Entries { get; set; }` on the User class to represent that side of the relationship. – levelnis Dec 16 '12 at 14:05
  • To represent this one to many relationship, i am keeping UserID in Entry model. Reason to make Entry as separate model class is that it is not just associated with User, Entry is also associated with another model 'Challenge'. – Fahad Dec 16 '12 at 14:16
  • Looks like one of these posts may help: http://stackoverflow.com/questions/851625/foreign-key-constraint-may-cause-cycles-or-multiple-cascade-paths and http://stackoverflow.com/questions/4150605/introducing-foreign-key-constraint-may-cause-cycles-or-multiple-cascade-paths – levelnis Dec 16 '12 at 14:21
0

You must disable cascading delete for at least one of the relationships EntryLike is involved in. Cascading delete is turned on by default for every required one-to-many relationship. You need Fluent API for this, it's not possible with data annotations. For example:

modelBuilder.Entity<EntryLike>()
    .HasRequired(el => el.Entry)
    .WithMany()
    .HasForeignKey(el => el.EntryID)
    .WillCascadeOnDelete(false);
Slauma
  • 175,098
  • 59
  • 401
  • 420