Does ignoring a base type in Entity Framework Code First also ignore subclasses?
Asked Answered
D

2

2

I'm attempting to simulate a scenario in which I am inheriting from concrete base classes in a 3rd party library, then mapping my own classes using Entity Framework Code First. I would really prefer for my classes to have the same simple name as the base classes. I obviously can't change the class names of the base classes, nor can I change the base class to abstract. As expected, I get the following error:

The type 'EfInheritanceTest.Models.Order' and the type 'EfInheritanceTest.Models.Base.Order' both have the same simple name of 'Order' and so cannot be used in the same model. All types in a given model must have unique simple names. Use 'NotMappedAttribute' or call Ignore in the Code First fluent API to explicitly exclude a property or type from the model.

As I understand it, in EF6 this is possible so long as only one of the classes is actually mapped. However, if I attempt to ignore the base class using the fluent API, I get the following error instead:

The type 'EfInheritanceTest.Models.Order' was not mapped. Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive or generic, and does not inherit from EntityObject.

... which seems to indicate that by ignoring the base class, I ignore any subclasses as well. Full code below. Any way to work around this and "unignore" the subclass? Or is this a limitation of EF type mapping?

namespace EfInheritanceTest.Models.Base
{
    public class Order
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual decimal Amount { get; set; }
    }
}

namespace EfInheritanceTest.Models
{
    public class Order : Base.Order
    {
        public virtual DateTime OrderDate { get; set; }
    }
}

namespace EfInheritanceTest.Data
{
    public class OrdersDbContext : DbContext
    {
        public OrdersDbContext() : base ("OrdersDbContext") { }

        public IDbSet<EfInheritanceTest.Models.Order> Orders { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Types<Models.Base.Order>().Configure(c => c.Ignore());
            modelBuilder.Types<Models.Order>().Configure(c => c.ToTable("order"));
            modelBuilder.Entity<Models.Order>().Map(c =>
                                                    {
                                                        c.MapInheritedProperties();
                                                        c.ToTable("order");
                                                    });

        }
    }
}
Dys answered 17/7, 2014 at 23:1 Comment(6)
Can you make the base class abstract?Simple
I should add that when I make an EF project, I almost always have a base abstract class with an int Id property to be used as my primary key so I know it can be done. I don't use the fluent API though.Simple
In the scenario I am simulating, base class is in the 3rd party lib that I can't change.Dys
I've just grabbed one of my older projects and removed the abstract property from my class and it still worked. However, if I added the model builder ignore code, I got the same error as you.Simple
If you are adding the Ignore, you may need to not call base.OnModelCreating(modelBuilder);. Seems to work for me.Simple
I removed the base call and I still get the error -- are you saying you don't get the "not mapped" error if you have the Ignore w/ no call to base.OnModelCreating?Dys
B
3

It's a bit late, anyway: I was able to solve the issue with very simple configuration:

modelBuilder.Ignore<MyBaseClass>();

So EF don't care about MyBaseClass at all, but works with MyInheritedClass as it is not. Perfect!

The second error was related to:

 modelBuilder.Types<Models.Base.Order>().Configure(c => c.Ignore());

as you excluded both classes from EF mapping (it excludes all hierarchy from Models.Base.Order).

There is also an excellent post on EF inheritance mapping.

Beedon answered 18/8, 2017 at 17:47 Comment(0)
D
0

I don't think that this will work if the child class has the same name as the parent class. I've definitely done this where the derived class has a different name than the parent class, but I doesn't look like this is possible when the names are the same (which I didn't know before). To test it, I took one of my projects where the inheritance was working with EF and I changed the names to fit the naming scheme that you have above and I'm getting the same errors that you list. It looks like this might be a limitation of the EF type mapping. Are you able to change the name of your derived class to be different than the parent?

Dulcie answered 18/7, 2014 at 19:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.