10

I am attempting to use code first and the fluent API to create an object that holds two different entities from the same table. In other words, a transfer object holds a reference to two different tank objects--one is the source and the other the destination.

However, when I use the following code I get an Exception stating that "The referential relationship will result in a cyclical reference that is not allowed."

modelBuilder.Entity<Transfer>()
            .HasRequired<Tank>(t => t.Source)
            .WithMany(t => t.OutboundTransfers);
modelBuilder.Entity<Transfer>()
            .HasRequired<Tank>(t => t.Destination)
            .WithMany(t => t.InboundTransfers);

My best guess is that it thinks I am pointing both keys to the same Tank? Any idea how I can accomplish this?

EDIT: Found the answer as adding .WillCascadeOnDelete(false) from Entity Framework Code First - two Foreign Keys from same table

Community
  • 1
  • 1
Matthew
  • 101
  • 4
  • 2
    Yea, you can't let EF 4.1 enable cascade delete constraints when two navigation properties are pointing to the same table. to enable the proper constraints, you will need to add them manually in the database using the Seeding objects to execute the proper scripts. – Alexandre Brisebois May 17 '11 at 11:54
  • That's it, as you have found and as Alexandre also pointed. Doing it manually on the MSSMS throws the error "Unable to create relationship (...) may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints." – Anderson Matos Sep 18 '12 at 22:42
  • 1
    Can you add your solution as an answer and mark it? – sinelaw Oct 17 '12 at 01:26

2 Answers2

1

As you stated, you should be able to add .WillCascadeOnDelete(false) - https://stackoverflow.com/a/5559300/5416

modelBuilder.Entity<Transfer>()
        .HasRequired<Tank>(t => t.Source)
        .WithMany(t => t.OutboundTransfers)
        .WillCascadeOnDelete(false);
modelBuilder.Entity<Transfer>()
        .HasRequired<Tank>(t => t.Destination)
        .WithMany(t => t.InboundTransfers)
        .WillCascadeOnDelete(false);

I just added this answer so that it doesn't show on the unanswered list any more as unanswered with zero answers. Marked as community wiki :)

Community
  • 1
  • 1
Joel Martinez
  • 46,929
  • 26
  • 130
  • 185
0

As usual Ladislav (EF Guru) has the answer to EF questions. (thanks Ladislav) Just an alternate i have found useful. I have an second solution I run in parallel. If I every have a code first issue. I first try thi: The reverse engineer to code first solution.(from EF power tools)

I have a test DB where I add the required concept by hand in a DB. I still find doing this in the DB more intuitive as im new to code first. Then using the powertool http://visualstudiogallery.msdn.microsoft.com/72a60b14-1581-4b9b-89f2-846072eff19d

on the Project/Solution right click Entity framework, reverse engineer DB to code first.

Check out the code it generartes. you get an example of how to do somethings.

phil soady
  • 11,043
  • 5
  • 50
  • 95