2010-10-14 7 views
1

У меня много проблем с «базовыми типами» в модели только для кода Entity Framework. У меня много проблем с «базовыми типами» в модели Code Only Entity Framework.Базовые типы с EntityFramework CodeOnly

Когда я пытаюсь запустить этот код с помощью DbContext с DbSet<Template>, я получаю следующее сообщение об ошибке.

A Свойство навигации «Флаги» сопоставляется с двумя разными таблицами соединений «page.flags» и «template.flags». Может существовать только одно отображение свойства навигации.

Это говорит мне о том, что я не могу отображать унаследованные свойства. Это довольно ломает много объектно-ориентированного кода. Есть ли известное средство? Я понимаю, что могу сделать Layout не абстрактным и иметь поддержку для него, но очень очевидно, что это не намерение модели домена. Абстрактный класс является основополагающей базой, а не хранимой моделью.

Я хотел бы добавить, если я положил IList<Flag> в класс Template, этот код работает. Поле Id все еще работает, даже через наследование. Я не понимаю, почему это происходит. Может кто-нибудь просветить меня?

public abstract class Layout 
{ 
    public virtual int Id 
    { 
     get; 
     set; 
    } 

    public virtual IList<Flag> Flags 
    { 
     get; 
     set; 
    } 
} 

public class Template : Layout 
{ 
    public virtual string Name 
    { 
     get; 
     set; 
    } 
} 

public class Page: Layout 
{ 
} 

public class LayoutConfiguration : EntityConfiguration<Layout> 
{ 
    public LayoutConfiguration() 
    { 
     HasKey(u => u.Id); 
     Property(u => u.Id).IsIdentity(); 

     MapHierarchy().Case<Page>(c => new 
     { 
      c.Id 
     }).ToTable("Pages"); 

     MapHierarchy().Case<Template>(c => new 
     { 
      c.Id, 
      c.Name 
     }).ToTable("Templates"); 
    } 
} 
public class TemplateConfiguration : EntityConfiguration<Template> 
{ 
    public TemplateConfiguration() 
    { 
     Property(o => o.Name).HasMaxLength(64).IsUnicode(); 

     HasMany(u => u.Flags).WithOptional() 
      .Map("template.flags", 
      (template, flag) => new { 
       Template = template.Id, 
       Flag = flag.Id 
      }); 

     MapSingleType(c => new { 
      c.Id, 
      c.Name 
     }).ToTable("templates"); 
    } 
} 

public class PageConfiguration : EntityConfiguration<Page> 
{ 
    public PageConfiguration() 
    { 
     HasMany(c => c.Flags).WithOptional() 
      .Map("page.flags", 
      (page, flag) => new 
      { 
       Page = page.Id, 
       Flag = flag.Id 
      }); 
    } 
} 

ответ

1

При использовании базового типа для объекта Template вы также должны моделировать это наследование при сопоставлении. Это означает, что вам нужно написать конфигурацию для макета, которая будет отображать идентификаторы и флаги и конфигурацию для шаблона, который будет отображать имя. Существует несколько подходов к отображению наследования в EF. Вероятно, вы должны проверить Table per Hiearchy.

Редактировать: На основе вашего комментария вы ищете Table per Class + examples for CTP4.

Редактировать2: Хорошо. Я протестировал ваш сценарий с помощью свойства навигации, определенного в абстрактном родительском классе, и он действительно не работает, если вы пытаетесь сопоставить его с несколькими таблицами.

+0

Однако это противоречит дизайну. Будут другие типы, которые наследуют от макета, им нужно, чтобы их флаги были сопоставлены с их соответствующими таблицами. – Ciel

+0

Во-первых - ваш объектно-ориентированный дизайн не должен соответствовать вашему дизайну базы данных. Во-вторых - проверьте одну и ту же статью, но прокрутите вниз до таблицы для каждого класса. –

+0

Это правда, что это работает для простых типов сопоставлений, таких как поле Id, но оно не работает для сопоставлений, таких как поле IList . Я должен был бы определить отношения HasMany в конфигурации Layout, и все наследователи должны были бы разделить таблицу отношений. Именно этого я и стараюсь избегать. Кроме того, ссылка приведена для CTP3, и большая часть ее устарела. – Ciel

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