Search code examples
c#entity-frameworkef-code-firstentity-framework-migrationsfluent

Entity Framework referencing columns in foreign key differs from number of referenced columns


I'm using Entity Framework code first, and I'm trying to get my migrations/database working (using the -update-database command), but I keep getting this error:

System.Data.SqlClient.SqlException (0x80131904): Number of referencing columns in foreign key differs from number of referenced columns, table 'dbo.FileSections'.

Which happens directly after this SQL Command (which EF is magic'ing up):

ALTER TABLE [dbo].[FileSections] ADD CONSTRAINT [FK_dbo.FileSections_dbo.Sections_Section_Id] FOREIGN KEY ([Section_Id]) REFERENCES [dbo].[Sections] ([Id], [EventName]) ON DELETE CASCADE

The simplified version of my issue is that an Event (Primary Key of string "Name") can have many Sections, and a Section (Primary Key of integer "Id") can have many Files (File with a Primary Key of string "Id"). The simplified classes are:

public class Event {
    public string Name { get; set; }
    public List<Section> Sections { get; set; }
}

public class Section {
    public int Id { get; set; }
    public string EventName { get; set; }
    public string Title { get; set; }
    public List<File> Files { get; set; }
}

public class File {
    public string Id { get; set; }
    public int SectionId { get; set; }
    public string FileName { get; set; }
}

I'm also using code first, and the setup for this is:

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    modelBuilder.Entity<Event>()
        .HasKey(X => X.Name);
    modelBuilder.Entity<Event>()
        .HasMany(X => X.Sections)
        .WithRequired(X => X.Event)
        .WillCascadeOnDelete();    

    modelBuilder.Entity<Section>()
        .HasKey(x => x.Id); 
    modelBuilder.Entity<Section>()
        .HasRequired(x => x.Event)
        .WithMany(x => x.Sections)
        .HasForeignKey(x => x.EventName);
    modelBuilder.Entity<Section>()
        .HasMany(x => x.Files)
        .WithRequired(x => x.Section)
        .HasForeignKey(x => x.SectionId)
        .WillCascadeOnDelete();

    modelBuilder.Entity<File>()
        .HasKey(x => x.Id);
    modelBuilder.Entity<File>()
        .HasRequired(x => x.Section)
        .WithMany(x => x.Files)
        .HasForeignKey(x => x.SectionId);
}

What am I doing wrong? I've also tried using composite primary keys (and therefore composite foreign keys), but this still gives me the same error. I really am at my wits end, surely it can't be this hard to have an entity containing entities that contain entities.


Solution

  • It turns out that Visual Studio 2013 was the issue - it was trying to apply the initial migration, not the actual latest one (despite the initial migration already being applied). I used this answer to fix the migration issues with VS.