2

I have two tables which are kind of problematic.

  • The first table is about users and has - userId, username, password, etc.

  • The second is handling messages, so it has - messageId, senderId, receiverId, messageContent.

As you can see, both senderId and receiverId need to be related to userId from the users table.

But as I'm trying to use Code First, it just crashes. I get an exception :

"Introducing FOREIGN KEY constraint 'FK_dbo.Messages_dbo.Users_ReceiverId' on table 'Messages' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints."

This is how I made the relations in the Message class :

    [ForeignKey("Sender")]
    public int SenderId { get; set; }
    public virtual User Sender { get; set; }

    [ForeignKey("Receiver")]
    public int ReceiverId { get; set; }
    public virtual User Receiver { get; set; }

Any ideas? I'm stuck right now. It works perfectly fine if I do it database-first, but not if I try it Code First.

Amith
  • 6,818
  • 6
  • 34
  • 45

4 Answers4

0

In the generated .cs file in the Migrations folder, replace cascadeDelete: true with cascadeDelete: false, so for example:

AddForeignKey("dbo.Messages", "ReceiverId", "dbo.Users", "Id", 
    cascadeDelete: true);
AddForeignKey("dbo.Messages", "SenderId", "dbo.Users", "Id", 
    cascadeDelete: true);

Becomes:

AddForeignKey("dbo.Messages", "ReceiverId", "dbo.Users", "Id", 
    cascadeDelete: false);
AddForeignKey("dbo.Messages", "SenderId", "dbo.Users", "Id", 
    cascadeDelete: false);
Alex Filipovici
  • 31,789
  • 6
  • 54
  • 78
  • For the record, if I only use a foreign key for one of the fields (for example only for Sender), it works flawlessly. However, the name of the receiver field would be something strange like "Receiver_User_UserId"... – Ivan Mladenov Oct 30 '13 at 15:58
0

By Default EF code first creates Cascade option set to true on Delete and Update Rule of Foreign Key table. you can check this from SQL Server management studio, by right clicking on the foreign key column of table then expand 'Insert and Update Specifications'. enter image description here

for quick solutions to this problem just add this code on DBContext.cs or YourContext.cs class which you have setup DBSet information.

 protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {            
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

    }

run the Add-Migration InitialContext command and Update-Database -Verbose command from Package manager console window of your project.

sridharnetha
  • 2,104
  • 8
  • 35
  • 69
0

I think your answer is in this post

Entity Framework 4.1 InverseProperty Attribute

It says there is another decorator called InverseAttrivuteProperty which helps you define which end of the relationship in the origin table matches which end on the destiny table.

But, don´t use it as it is explained. I had to leave your decorator on the Foreign Keys.

Just tested it and it worked. Soon I´ll post something explanatory.

Community
  • 1
  • 1
Ricker Silva
  • 1,137
  • 4
  • 17
  • 37
0

simply manually configure your entity relationships to avoid confusion to EF.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{            
    modelBuilder.Entity<Message>()
                .HasOptional(x => x.Sender)
                .WithMany(x => x.SenderMessages);
    modelBuilder.Entity<Message>()
                .HasOptional(x => x.Reciever)
                .WithMany(x => x.RecieverMessages);

}
Xinan
  • 3,002
  • 1
  • 16
  • 18