Как создать унаследованный класс, если в основе лежит DbContext EF4.1?

Наша команда использует Entity Framework 4.1 ORM. Мы не используем его в режиме Code First, но мы используем чистые функции генерации POCO из этой версии.

Мы столкнулись с тем, что хотим создать унаследованный класс на основе EF POCO, но пока единственный способ увидеть, как это происходит, — это иметь таблицу сопоставления в базе данных. Есть ли лучший способ создать этот унаследованный объект? Следующий код является примером того, о чем я говорю.

Этот класс создается:

public partial class Member
{
public Member()
{
    this.ContactAddresses = new HashSet<ContactAddress>();
    this.ContactEmails = new HashSet<ContactEmail>();
    this.FormDatas = new HashSet<FormData>();

    this.ContactPhones = new HashSet<ContactPhone>();
}

public int ID { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Alias { get; set; }
public string Title { get; set; }
public string Company { get; set; }
public string Prefix { get; set; }
public string Suffix { get; set; }
public System.DateTime CreatedDate { get; set; }
public int CreatedBy { get; set; }
public Nullable<System.DateTime> ModifiedDate { get; set; }
public Nullable<int> ModifiedBy { get; set; }
public Nullable<System.Guid> AspNetUserID { get; set; }

public virtual aspnet_Users aspnet_Users { get; set; }
public virtual ICollection<ContactAddress> ContactAddresses { get; set; }
public virtual ICollection<ContactEmail> ContactEmails { get; set; }
public virtual ICollection<FormData> FormDatas { get; set; }

public virtual ICollection<ContactPhone> ContactPhones { get; set; }
}

Это пример того, что мы хотели бы создать:

public class SpecificMember : Member 
{
public SpecificMember()
{
    this.Assignments = new HashSet<Assignment>();
    this.Expertises = new HashSet<Expertise>();
    this.Experiences = new HashSet<Experience>();
    }this.VendorInformations = new HashSet<VendorInformation>();

public virtual ICollection<Assignment> Assignments { get; set; }
public virtual ICollection<Expertise> Expertises { get; set; }
public virtual ICollection<Experience> Experiences { get; set; }
public virtual ICollection<VendorInformation> VendorInformations { get; set; }

}

Я действительно хотел бы держаться подальше от размещения еще одной таблицы в базе данных. Моя идея состоит в том, что здесь мы имеем дело только с классами, но я не уверен, как эти две сущности будут работать друг с другом.

Любые идеи о том, как это сделать при использовании Entity Framework или в коде, были бы замечательными. Заранее спасибо.


person Chris    schedule 12.05.2011    source источник


Ответы (3)


В EF4.1 это называется сложными типами, и у вас есть несколько доступных вариантов. Вы можете иметь их в отдельных таблицах (называемых «Таблица на тип») или в одной таблице (называемой «Таблица на иерархию»), что означает, что в таблицу будет добавлен столбец дискриминатора, чтобы сообщить EF, какой это тип.

Я еще не использовал его много, но в EF4.1 он кажется очень мощным.

Ознакомьтесь с этой статьей, состоящей из нескольких частей, чтобы получить хороший обзор работы с Сложные типы в EF4.1. Это написано против CTP5, но выглядит точным для меня.

Я думаю, что вам нужно на эта страница здесь.

Если вы выполняете сопоставление с существующей БД или хотите управлять своей схемой вручную, в этой статье есть еще один пример работы с этим сценарием для существующей базы данных.

person Gats    schedule 12.05.2011
comment
Эти сообщения в блоге хорошо объясняют различные типы наследования. Спасибо за ссылки! - person Chris; 13.05.2011
comment
Без проблем. Это хороший вопрос, о котором мы еще услышим по мере развития EF. Мне нравится подход только с кодом. - person Gats; 14.05.2011

У меня было подобное требование, в соответствии с которым я хотел использовать атрибуты для сгенерированных классов POCO (которые использовали шаблоны t4). Я получил следующий ответ от действительно хорошего EF Пользователь.

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

К сожалению, мы оба находимся в одной лодке, и потребуется немного компромисса или больше работы, чтобы получить то, что мы хотим. :)

person DotNetInfo    schedule 12.05.2011

Что вам нужно, так это сделать базовый класс Member абстрактным, а конкретныеMember и подобные классы — конкретными. Это создаст/потребует таблицу для каждой конкретной реализации абстрактного класса Member.

Каждый конкретный класс может отображаться в одной таблице. У вас может быть только один DbSet ‹concreteClass›, но вы можете использовать этот конкретный класс для хранения реляционной информации со многими различными таблицами.

В вашем примере вы можете повторно использовать FormData, ContactData, ContactAddress во многих разных сущностях, полученных от члена или чего-то совершенно другого.

Но если вам нужны разные классы для ContactData или ContactAddress, вам нужно выбрать один из соответствующих методов наследования, предоставляемых EF4.1.

person hazimdikenli    schedule 12.05.2011