2015-08-18 4 views
1

У меня есть таблица в существующей базе данных, которая выглядит примерно так:Entity Framework 6 Code First Fluent API Таблица Mapping

PK 
FK 
Col1 
Col2 
Col3 
Col4 
Col5 

Мне нужно, чтобы получить его в иерархии классов, как это:

public abstract class BaseClass : Entity 
{ 
    public int PK {get; set;} 
    public string Col1 {get; set;} 
} 

public class Child1 : BaseClass 
{ 
    public string Col2 {get; set;} 
    public string Col3 {get; set;} 
} 

public class Child2 : BaseClass 
{ 
    public string Col4 {get; set;} 
    public string Col5 {get; set;} 
} 

я в настоящее время с помощью Fluent API для настройки объектов следующим образом:

public abstract class BaseClassConfig<TEntity> : EntityTypeConfiguration<TEntity> where TEntity : Entity 
{ 
    public BaseClassConfig() 
    { 
     ToTable("TheTableName"); 
     HasKey(x => x.Id); 

     Property(x => x.Col1).HasColumnName("SomeName"); 
    } 
} 

public class Child1Config : BaseClassConfig<Child1> 
{ 
    public Child1Config() 
    { 
     Property(x => x.Col2).HasColumnName("SomeName"); 
     Property(x => x.Col3).HasColumnName("SomeName"); 
    } 
} 

public class Child2Config : BaseClassConfig<Child2> 
{ 
    public Child2Config() 
    { 
     Property(x => x.Col4).HasColumnName("SomeName"); 
     Property(x => x.Col5).HasColumnName("SomeName"); 
    } 
} 

Когда я добавил их в контексте что наследуется от DbContext:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Configurations.Add(new Child1Config()); 
    modelBuilder.Configurations.Add(new Child2Config()); 
} 

Я получаю следующее сообщение об ошибке:

The entity types 'Child1' and 'Child2' cannot share table 'TheTableName' because they are not in the same type hierarchy or do not have a valid one to one foreign key relationship with matching primary keys between them.

Я посмотрел на эту статью: http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/implementing-inheritance-with-the-entity-framework-in-an-asp-net-mvc-application

Но это на самом деле не говорить об использовании свободно API для настройте типы, а просто добавьте их в контекст через DbSet<>.

Как настроить отдельную таблицу для сопоставления с различными классами через базовый класс с использованием свободного api?

+0

Почему вы разделяете класс сущности на три класса? Также, как вы определили имя таблицы в абстрактном BaseClassConfig и реализуете его в двух других классах ChildConfig, что не уточняет фактическую сущность, которая должна отображаться в базе данных. Как вы называете эту конфигурацию? Если вам нужна структура таблицы, то класс child2 должен наследовать от дочернего 1 и переместить вызов ToTableName в Child2Config –

+0

@SandeepKumar. Поскольку «BaseClass» имеет общие свойства как «Child1», так и «Child2», тогда как каждый из них имеет свои собственные свойства не связанные друг с другом. Это наследование в простейшей форме. Но в этом случае существующая схема имеет все свойства, хранящиеся в одной таблице. – Sam

+0

Для EF, организации должны быть сопоставлены с таблицами базы данных. Цель EF-кода в первую очередь - связать сущность с таблицей базы данных, и сущности должны использоваться только для этой цели. Если вы намерены что-то сделать с этой иерархией классов, сначала создайте простой объект для таблицы, и после этого вы должны создать другие классы (например, DTO) с этой иерархией и использовать их в своем приложении. Используйте automapper или создайте методы сопоставления для обработки вашего запроса от DTO до Entity. Это перенесет вашу специфическую ответственность за приложения из объектов в DTO. –

ответ

1

Хорошая ссылка я перехожу к большому эта статья MSDN: Configuring/Mapping Properties and Types with the Fluent API

В нем вы увидите ссылку на таблицу-Per-иерархии (TPH) модель наследования. По сути, вы отсутствуете в поле discinator (и на основании ошибки FK также не отображается).

По умолчанию столбец дискриминатора называется Discriminator, но как вы можете видеть из статьи, это может быть изменено в коде первого отображения:

modelBuilder.Entity<Course>() 
    .Map<Course>(m => m.Requires("Type").HasValue("Course")) 
    .Map<OnsiteCourse>(m => m.Requires("Type").HasValue("OnsiteCourse")); 

В приведенном выше примере, Type является дискриминатором что позволяет EF знать, какой тип объекта материализуется, т.е. объект Course, когда Type == "Course".

+0

Хорошо, но как использовать свободно api для описания свойств на 'Child2' на EF? Нехорошо ли использовать шаблон наследования для плавных конфигураций? – Sam

+1

Я бы не стал использовать наследование для конфигураций отображения. По соглашению свойства будут отображаться правильно, но если вам нужно настроить его, вы можете сделать в lambda 'Map' каждого производного типа. Посмотрите, поможет ли здесь ответ: http://stackoverflow.com/questions/23366489/ef6-tph-mapping-of-derived-property-to-specific-table-specific-column –

+1

Направил меня в правильном направлении и Ответ тоже помог мне. Огромное спасибо! Но еще один вопрос: как вы отмечаете свойства производного типа, необходимые для свободного использования api? Я заметил, что функция 'Property()' отличается от функции map. – Sam

Смежные вопросы