1

Closed

One to one issue in TPC hierarchy with mapped abstract base class

description

Hi,
I have a TPC hierarchy like this:
    public abstract class Base
    {
        public Guid BaseId { get; set; }
        public string BaseName { get; set; }
    }
    public class Sub1 : Base
    {
        public Sub2 Vender { get; set; }
    }
    public class Sub2 : Base
    {
        public Sub1 Customer { get; set; }
    }
    public class MyDbContext : DbContext
    {
        public MyDbContext()
            : base("name=db")
        { }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Sub1>().HasRequired(x => x.Vender).WithOptional(x => x.Customer);
            modelBuilder.Entity<Sub1>().Map(x =>
                {
                    x.ToTable("Sub1s");
                    x.MapInheritedProperties();
                });
            modelBuilder.Entity<Sub2>().Map(x =>
                {
                    x.ToTable("Sub2s");
                    x.MapInheritedProperties();
                });
        }

        public DbSet<Base> People { get; set; }
        public DbSet<Sub2> Venders { get; set; }
        public DbSet<Sub1> Customers { get; set; }
    }
Then I run the code and EF create tables (Sub1s and Sub2s).
But EF create an aditional Foreign Key for table Sub1, it do not use the Key of Sub1 as the Foreign Key..
Closed Jul 17, 2013 at 12:37 AM by maumar
Agree that this is by design. closing

comments

Lcng wrote Jun 10, 2013 at 9:03 AM

create tables (Sub1s and Sub2s).
But EF create an aditional Foreign Key for table Sub1, it do not use the Key of Sub1 as the Foreign Key..

RoMiller wrote Jun 13, 2013 at 11:47 PM

EF Team Triage: Assigning to a member of the EF team for further investigation.

BriceLambson wrote Jun 19, 2013 at 12:24 AM

This type of mapping is supported in EDM; however, when the abstract base class in included in the model (via the DbSet<Base> property), for some reason, Code First splits the primary key and foreign key into two columns.

One workaround is to exclude Base from the model using modelBuilder.Ignore<Base>()

Lcng wrote Jun 19, 2013 at 7:54 AM

Thank you, BriceLambson.
When I ignore the abstract class Base, I can not hvae a 'DbSet<Base>' which is necessary for me..

divega wrote Jun 29, 2013 at 1:25 AM

Note for the dev working on this: We have seen a few bugs related to TPC scenarios recently. I recommend doing a quick search for TPC in the bug database in case some are related to this one.

emilcicos wrote Jul 16, 2013 at 8:53 PM

Unless I am missing something this appears to be by design. If using the Key of Sub1 as Foreign Key the constraint would require the Ids from Sub1s to match those from Sub2s. That conflicts with DbSet<Base> which implies the Ids for venders and customers should be different. Please reactivate if you think otherwise.

Lcng wrote Jul 17, 2013 at 2:09 AM

"If using the Key of Sub1 as Foreign Key the constraint would require the Ids from Sub1s to match those from Sub2s. That conflicts with DbSet<Base> which implies the Ids for venders and customers should be different."

Thank you emilcicos.
You are right, I was wrong..