Reputation: 1499
There are 3 entities:
User has ICollection<Event>
and ICollection<Review>
.
Event has virtual User navigation property, and ICollection<Review>
Structure of Review class
public int Id { get; set; }
public string Text { get; set; }
public int Mark { get; set; }
public ReviewStatus ReviewStatus { get; set; }
public int EventId { get; set; }
public virtual Event Event { get; set; }
public int UserId { get; set; }
public virtual AppUser User { get; set; }
And i got - Introducing FOREIGN KEY 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.
I can solve it by adding this on ModelCreating
method of DbContext
:
modelBuilder.Entity<Event>().
HasMany(e => e.Reviews).
WithRequired(e => e.Event).
WillCascadeOnDelete(false);
modelBuilder.Entity<AppUser>().
HasMany(u => u.Reviews).
WithRequired(r => r.User).
WillCascadeOnDelete(false);
But after this I can't delete Event or user from database, because foreign key error occurs. So is there another solution?
Upvotes: 1
Views: 127
Reputation: 3355
You should decide between not being able to delete or inserting null in places of foreign-key when you delete, you can let the User
to be deleted and insert null for any deleted Event
that was foreignkey in Review
and have orphaned Review
, here is the code for making Event
to Review
relationship nullable:
modelBuilder.Entity<Review>()
.HasOptional(t => t.Event)
.WithMany(t => t.Reviews)
.HasForeignKey(d => d.EventId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Review>()
.HasOptional(p => p.Event)
.WithMany(p => p.Reviews)
.HasForeignKey(p => p.EventId);
also remember to lazy load the Event
and Review
with Include
when deleting the user otherwise null
will not get inserted, other point to make is that remember when you face situations like this when User
have many Events
and Events
have many Reviews
you have to do the null insertion for Event
to Review
yourself, EF doesn't do this for you, something like blow example:
var eventItems = _db.Events.Include(p => p.Reviews).(s => s.UserIdfk == UserId);
foreach (var item in eventItems)
{
_db.Events.Remove(item);
}
I hope I've been able to convey the general approach.
Upvotes: 1