I'm developing a library with Entity Framework 6.1.0 Code First, .NET Framework 4.5, C# and SQL Server.
I have these two classes:
public class User
{
public int UserId { get; set; }
public string UserName { get; set; }
public ICollection<Group> Groups { get; set; }
public ICollection<Message> MessagesSent { get; set; }
public ICollection<Message> MessagesReceived { get; set; }
}
public class Message
{
public int MessageId { get; set; }
public string Body { get; set; }
public DateTime DateSent { get; set; }
public int UserId { get; set; }
public User Sender { get; set; }
public ICollection<User> Recipients { get; set; }
}
And these configurations file:
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
ToTable("User");
Property(u => u.UserName).IsRequired();
Property(u => u.UserName).HasMaxLength(50);
HasMany(u => u.Groups).
WithMany(g => g.Members).
Map(ug =>
{
ug.MapLeftKey("UserId");
ug.MapRightKey("GroupId");
ug.ToTable("UserGroup");
});
}
}
public class MessageConfiguration : EntityTypeConfiguration<Message>
{
public MessageConfiguration()
{
ToTable("Message");
Property(m => m.Body).IsRequired();
Property(m => m.Body).IsMaxLength();
Property(m => m.DateSent).IsRequired();
HasRequired(m => m.Sender).
WithMany(u => u.MessagesSent).
HasForeignKey(m => m.UserId);
HasMany(r => r.Recipients).
WithMany(m => m.MessagesReceived).
Map(mr =>
{
mr.ToTable("MessageRecipient");
mr.MapLeftKey("MessageId");
mr.MapRightKey("UserId");
});
}
}
The first time I run this project I get the following message:
Introducing FOREIGN KEY constraint 'FK_dbo.MessageRecipient_dbo.User_UserId' on table
'MessageRecipient' 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.
Users won't be deleted from my database, but I don't know how to fix this problem.
I think the problem is that a message has a sender (an user
) and also has one or more recipients (user
). This creates different cascade paths (which is not allowed with SQL Server).
How can I disable those cascade paths? Maybe on Message.Sender
.
I have solved my problem.
Before I had on MessageConfiguration
:
HasRequired(m => m.Sender).
WithMany(u => u.MessagesSent).
HasForeignKey(m => m.UserId);
Now I have:
HasRequired(m => m.Sender).
WithMany(u => u.MessagesSent).
HasForeignKey(m => m.UserId).
WillCascadeOnDelete(false);
The problem is that SQL Server doesn't allow multiple cascade paths. If you delete an user you could have two delete cascade on Message
: one on Message.Sender
and another one on Message.Recipients
.