Игнорирование базового типа в Entity Framework Code First также игнорирует подклассы?

Я пытаюсь смоделировать сценарий, в котором я наследую конкретные базовые классы в сторонней библиотеке, а затем сопоставляю свои собственные классы с помощью Entity Framework Code First. Я действительно предпочел бы, чтобы мои классы имели то же простое имя, что и базовые классы. Я, очевидно, не могу изменить имена базовых классов, а также не могу изменить базовый класс на абстрактный. Как и ожидалось, я получаю следующую ошибку:

Тип «EfInheritanceTest.Models.Order» и тип «EfInheritanceTest.Models.Base.Order» имеют одно и то же простое имя «Order» и поэтому не могут использоваться в одной и той же модели. Все типы в данной модели должны иметь уникальные простые имена. Используйте NotMappedAttribute или вызовите Ignore в свободном API Code First, чтобы явно исключить свойство или тип из модели.

Насколько я понимаю, в EF6 это возможно, пока фактически отображается только один из классов. Однако, если я попытаюсь игнорировать базовый класс, используя свободный API, вместо этого я получу следующую ошибку:

Тип «EfInheritanceTest.Models.Order» не сопоставлен. Убедитесь, что тип не был исключен явным образом с помощью метода Ignore или аннотации данных NotMappedAttribute. Убедитесь, что тип был определен как класс, не является примитивным или универсальным и не наследуется от EntityObject.

... что, по-видимому, указывает на то, что, игнорируя базовый класс, я также игнорирую любые подклассы. Полный код ниже. Есть ли способ обойти это и «не игнорировать» подкласс? Или это ограничение сопоставления типов EF?

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");
                                                    });

        }
    }
}

person nickwesselman    schedule 17.07.2014    source источник
comment
Можно ли сделать базовый класс абстрактным?   -  person DavidG    schedule 18.07.2014
comment
Я должен добавить, что когда я делаю проект EF, у меня почти всегда есть базовый абстрактный класс со свойством int Id, который будет использоваться в качестве моего первичного ключа, поэтому я знаю, что это можно сделать. Однако я не использую свободный API.   -  person DavidG    schedule 18.07.2014
comment
В сценарии, который я моделирую, базовый класс находится в сторонней библиотеке, которую я не могу изменить.   -  person nickwesselman    schedule 18.07.2014
comment
Я только что взял один из своих старых проектов и удалил абстрактное свойство из своего класса, и он все еще работал. Однако, если я добавлю код игнорирования конструктора моделей, я получу ту же ошибку, что и вы.   -  person DavidG    schedule 18.07.2014
comment
Если вы добавляете игнорирование, вам может потребоваться не вызывать base.OnModelCreating(modelBuilder);. Кажется, работает для меня.   -  person DavidG    schedule 18.07.2014
comment
Я удалил базовый вызов, и я все еще получаю сообщение об ошибке - вы говорите, что не получаете ошибку несопоставления, если у вас есть Ignore без вызова base.OnModelCreating?   -  person nickwesselman    schedule 18.07.2014


Ответы (2)


Я не думаю, что это сработает, если дочерний класс имеет то же имя, что и родительский класс. Я определенно сделал это, когда производный класс имеет другое имя, чем родительский класс, но я не похоже, что это возможно, когда имена одинаковы (чего я не знал раньше). Чтобы проверить это, я взял один из своих проектов, где наследование работало с EF, и я изменил имена, чтобы они соответствовали схеме именования, которая у вас есть выше, и я получаю те же ошибки, которые вы перечисляете. Похоже, это может быть ограничением сопоставления типов EF. Можете ли вы изменить имя вашего производного класса, чтобы оно отличалось от родительского?

person greyseal96    schedule 18.07.2014

В любом случае, немного поздно: я смог решить проблему с очень простой конфигурацией:

modelBuilder.Ignore<MyBaseClass>();

Таким образом, EF вообще не заботится о MyBaseClass, но работает с MyInheritedClass, поскольку это не так. Идеально!

Вторая ошибка была связана с:

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

поскольку вы исключили оба класса из сопоставления EF (исключая всю иерархию из Models.Base.Order).

Также есть отличный пост на сопоставление наследования EF.

person Vladislav Kostenko    schedule 18.08.2017