1

Closed

Moving from EF5 -> EF6: Invalid Column Name error

description

Hi, I'm investigating migration from EF5 to EF 6.0.1 for our application and I think I've identified a bug in EF6 that was not present in EF5.

I now get Invalid Column Name exceptions when querying some models that worked fine before.

I've attached a solution that reproduces the problem we are experiencing, and also what the resolution is - if you uncomment the line that ignores the COSwap model during model creation, the error is resolved.

Basically, it looks like EF6 cannot handle navigation / FK property pairs that have the same name in totally unrelated areas of the model hierarchy - the COSwap and IRSwap models both have a ReceiveLeg association, and the invalid column name is ReceiveLegId1.

Please let me know when a fix will be available for this.

Thanks,

Sam

file attachments

Closed Jan 21 at 6:04 PM by BriceLambson

comments

maumar wrote Oct 28, 2013 at 6:00 PM

I was able to repro this on EF 6.0.1 as well as current nightly.

maumar wrote Oct 29, 2013 at 12:23 AM

Simplified repro:
namespace EF6Problems
{
    using System;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity;
    using System.Linq;

    public class DomainModelContext : DbContext
    {
        public DomainModelContext(string connectionString)
            : base(connectionString)
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Instrument>().HasKey(p => p.Id);
            modelBuilder.Entity<Instrument>().Property(p => p.Id).IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

            modelBuilder.Entity<Instrument>().ToTable(typeof(Instrument).Name);

            modelBuilder.Entity<IRTrade>().ToTable(typeof(IRTrade).Name);

            modelBuilder.Entity<LoanDeposit>().Map<LoanDeposit>(m => m.Requires("Discriminator").HasValue(1));
            modelBuilder.Entity<LoanDeposit>().Map<IndexedSwapLeg>(m => m.Requires("Discriminator").HasValue(2));
            modelBuilder.Entity<LoanDeposit>().Map<IRSwap>(m => m.Requires("Discriminator").HasValue(3));
            modelBuilder.Entity<LoanDeposit>().Map<Swaption>(m => m.Requires("Discriminator").HasValue(4));
            modelBuilder.Entity<LoanDeposit>().ToTable(typeof(LoanDeposit).Name);

            modelBuilder.Entity<COSwap>().HasRequired(s => s.ReceiveLeg).WithMany().HasForeignKey(s => s.ReceiveLegId);
            modelBuilder.Entity<COSwap>().ToTable(typeof(COSwap).Name);            
            
            // UNCOMMENT either to fix issue
            //modelBuilder.Ignore<COSwap>();
            //modelBuilder.Ignore<Swaption>();
        }
    }

    public class Instrument
    {
        public int Id { get; set; }
    }

    // this can also be removed to repro this issue, but fails in EF5 due to another bug
    public class IRTrade : Instrument
    {
    }
        
    public class COSwap : Instrument
    {
        public int ReceiveLegId { get; set; }
        public Instrument ReceiveLeg { get; set; }
    }

    public class LoanDeposit : IRTrade
    {
    }

    public class IndexedSwapLeg : LoanDeposit
    {
    }

    public class IRSwap : LoanDeposit
    {
        public int? ReceiveLegId { get; set; }

        public LoanDeposit ReceiveLeg { get; set; }
    }

    public class Swaption : IRSwap
    {
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Database.SetInitializer<DomainModelContext>(null);

            using (var context = new DomainModelContext(@"Data Source=.\Sqlexpress;Initial Catalog=Bug1776;Integrated Security=True;MultipleActiveResultSets=True"))
            {
                var loan = context.Set<LoanDeposit>().Where(ld => ld.Id == 0);

                Console.WriteLine(loan);
                loan.ToList();
            }
        }
    }
}
And Sql script:
CREATE TABLE [dbo].[Instrument] 
(
    [Id] int CONSTRAINT [DF_Instrument_Id]  NOT NULL,
    CONSTRAINT [PK_Instrument] PRIMARY KEY CLUSTERED ([Id] ASC)
);

CREATE TABLE [dbo].[IRTrade] 
(
    [Id] int NOT NULL,
    CONSTRAINT [PK_IRTrade] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_IRTrade_Instrument] FOREIGN KEY ([Id]) REFERENCES [dbo].[Instrument] ([Id]) ON DELETE CASCADE
);

CREATE TABLE [dbo].[COTrade] 
(
    [Id] int NOT NULL
    CONSTRAINT [PK_COTrade] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_COTrade_Instrument] FOREIGN KEY ([Id]) REFERENCES [dbo].[Instrument] ([Id])
);


CREATE TABLE [dbo].[COSwap] 
(
    [Id] int NOT NULL,
    [ReceiveLegId] int NOT NULL,
    CONSTRAINT [PK_COSwap] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_COSwap_Instrument] FOREIGN KEY ([Id]) REFERENCES [dbo].[Instrument] ([Id]) ON DELETE CASCADE,
    CONSTRAINT [FK_COSwap_ReceiveLeg] FOREIGN KEY ([ReceiveLegId]) REFERENCES [dbo].[COForward] ([Id])
);

CREATE TABLE [dbo].[LoanDeposit]
(
    [Id] int NOT NULL,
    [Discriminator] TINYINT NOT NULL,
    [ReceiveLegId] int NULL,
    [IndexedReceiveLegId] int NULL
    CONSTRAINT [PK_LoanDeposit] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_LoanDeposit_IndexedReceiveLeg] FOREIGN KEY ([IndexedReceiveLegId]) REFERENCES [dbo].[LoanDeposit] ([Id]),
    CONSTRAINT [FK_LoanDeposit_IRTrade] FOREIGN KEY ([Id]) REFERENCES [dbo].[IRTrade] ([Id]) ON DELETE CASCADE,
    CONSTRAINT [FK_LoanDeposit_ReceiveLeg] FOREIGN KEY ([ReceiveLegId]) REFERENCES [dbo].[LoanDeposit] ([Id])
);

emilcicos wrote Nov 15, 2013 at 5:52 PM

Fixed in changeset 86d31f93dbe29c2df1c8f1cb56ec1c1e75d31941

BriceLambson wrote Jan 20 at 7:18 PM

Fixed in changeset 408b5b801660c4897abedd439f1327e893b7dfde