3

I had invest now one day to find a solution wihtout success.

I like to create a simple Many to Many relation.

For that I've created two Models:

A Player class where i will have the 'Turnaments' navigation property to see which turnaments has visit a player.

public class Player
{
    [Key]
    public Int64 PlayerId { get; set; }

    public string FirstName { get; set; }

    [Required]
    public string Surename { get; set; }

    public virtual ICollection<Turnament> Turnaments { get; set; }
}

and a Turnament class where I will have the 'Players' navigation property to see which players a part of the turnament.

public class Turnament
{
    [Key]
    public int TurnamentId { get; set; }

    [Required]
    public string Name { get; set; }

    public DateTime? StartDate { get; set; }

    public DateTime? EndDate { get; set; }

    public bool IsClosed { get; set; }

    public virtual ICollection<Player> Players { get; set; }
}

If start the mirgation of by the command 'upate-database' (automtic migratons = on) at the 'Package Manager Console' window of VS2012 - I get the following exception:

Introducing FOREIGN KEY constraint 'FK_dbo.PlayerTurnaments_dbo.Turnaments_Turnament_TurnamentId' on table 'PlayerTurnaments' 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.

Also the Background of that Exception I understand.

So I will reach to tell the entity-framwork that if I'm delete:

a) A Player EF should not push a cascade delete to the associated Turnament

b) A Turnament EF should push a cascade delete to the accociated Player

with that Background the cycles paths are gone.

So I was try to implement a 'Switch cascade delete off' via the fluent-API of Entity Framwork:

public class DataContext : DbContext
{
    public DbSet<Turnament> Turnaments { get; set; }
    public DbSet<Player> Players { get; set; }

    protected override void OnModelCreating( DbModelBuilder modelBuilder )
    {

        //modelBuilder.Entity<Turnament>()
        //    .HasMany( b => b.Players )
        //    .WithMany( a => a.Turnaments )
        //    .Map( m => m.MapLeftKey( "PlayerPid" )
        //                  .MapRightKey( "TurnamentPid" )
        //                  .ToTable( "TurnamentsJoinPlayers" ) );


        //modelBuilder.Entity<Player>().HasRequired( t => t.Turnaments ).
        //    WithMany().WillCascadeOnDelete( false );

        //modelBuilder.Entity<Turnament>().HasRequired( t => t.Players ).
        //    WithMany().WillCascadeOnDelete( false );

        //modelBuilder.Entity<Player>().HasRequired( t => t.TurnamentsRelation ).
        //    WithMany().HasForeignKey( p => p.PlayerId ).WillCascadeOnDelete( false );

        //modelBuilder.Entity<Player>().HasMany(p => p.TurnamentsRelation).

        base.OnModelCreating( modelBuilder );

    }
}

But as you see everthing is commend out because its don't help.

thx for all competent help with more as only some code snippes that only cracks understand :) PS: I'm sure there is a solution for EF5 (final) of that kind of many-to-many relations

Michael Maier
  • 123
  • 1
  • 9
  • What was the model like before migration? – Gert Arnold Dec 03 '12 at 09:45
  • Do you have just those two entities in the model? The exception message may be misleading. – Ladislav Mrnka Dec 03 '12 at 11:11
  • @GertArnold: Before the Navigation Propertys 'Turnaments' and 'Players' dont exsist. So the initial Migration had create the Database with the two tables. – Michael Maier Dec 03 '12 at 20:52
  • @Ladislav Mrnka: Yes, for that example I have only two entities. The exception is not misleading, because that two entities really create cascaded updated/delete cycles path. My problem is how I can turn off the cascade delete via fluent-api for case 'a)' above. – Michael Maier Dec 03 '12 at 20:58
  • All the technical background from that what I'm speaking from is to see at that video: http://channel9.msdn.com/Shows/Web+Camps+TV/Rowan-Miller-Demonstrates-Entity-Framework-5-Using-ASPNET-MVC-4 – Michael Maier Dec 03 '12 at 21:09

1 Answers1

2

SOLUTION

public class MyAppContext : DbContext
{

   public MyAppContext()
   {
    // Somtimes helps to uncommend that line, then the Database will recreated!
    // (For people that are not fit enough in EF CodeFirst - like me ;)
    // 1) Uncommend 
    // 2) Start Application go on a site that access your data wait for
    //    Exception (No Database!)
    // 3) Unkommend line 
    // 4) Execute 'update-database' at the 'Package Manager Console' of VS 2012
    // Database.SetInitializer(new DropCreateDatabaseAlways<LivescoreContext>());
   }

   protected override void OnModelCreating( DbModelBuilder modelBuilder )
   {
        /* Players <-> Turnaments */
        modelBuilder.Entity<Player>()
            .HasMany( p => p.Turnaments )
            .WithMany( p => p.Players )
            .Map( mc =>
                {
                    mc.MapLeftKey( "PlayerPid" );
                    mc.MapRightKey( "TurnamentPid" );
                    mc.ToTable( "PlayersJoinTurnaments" );
                } );

        base.OnModelCreating( modelBuilder );
   }
}
Michael Maier
  • 123
  • 1
  • 9