2013-09-19 3 views
15

Я собираюсь использовать Entity Framework в ближайшее время для системы бронирования (сделанной с нуля).Entity Framework Полиморфные ассоциации

Я делаю несколько прототипов, пытаясь выяснить, что я хочу сделать до начала проекта (я все еще обсуждаю требования и т. Д. С клиентом).

Рассмотрим этот случай:

У меня есть заказ, и заказ может быть связано RESSOURCES, которые могут быть забронированы, но эти Ressource могут быть разные, и имеют разные поля и т.д.

ER Diagram of the Relationship

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

C# модель будет выглядеть следующим образом:

public class Booking 
{ 
    public int BookingID { get; set; } 
    public DateTime StartTime { get; set; } 
    public DateTime EndTime { get; set; } 
    public IRessource Ressources { get; set; } 
    ... 
} 

public interface IRessource 
{ 
    public int RessourceTypeId { get; set; } 
} 

public class Room : IRessource 
{ 
    public int RoomID { get; set; } 
    public int RessourceTypeId { get; set; } 
    ... 
} 

public class Car : IRessource 
{ 
    public int CarID { get; set; } 
    public int RessourceTypeId { get; set; } 
    ... 
} 

Является ли это достижимо, и если да, то как? Как бы выглядел запрос?

+0

Взгляните на это: http://weblogs.asp.net/manavi/archive/2010/12/28/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-2 -table-per-type-tpt.aspx –

+8

В качестве побочного примечания правильная орфография является «ресурсом», с одним «s», а не «ressources» с двумя «s» s. –

+0

@Cupcake, я нашел это позже ^^ –

ответ

20

Да, абсолютно.

Похоже, вы действительно хотите отношения Table Per Type (TPT). Это представляет собой стандартные отношения внешних ключей is-a/has-a. Обратите внимание, что по умолчанию Entity Framework использует таблицу для иерархии (TPH).

Вот некоторые ссылки:

Я настоятельно рекомендую вам пройти через некоторые из этих ссылок на свой собственный, но главное, чтобы извлечь что вы используете что-то вроде:

modelBuilder.Entity<IRessource>().ToTable("IRessources"); 
modelBuilder.Entity<Room>().ToTable("Rooms"); 
modelBuilder.Entity<Car>().ToTable("Cars"); 

Оба из них наследуют от IRessource в вашем продемонстрированном коде выше. Затем вы можете сделать соединение между этими отдельными таблицами и центральной таблицей IRessource, чтобы получить всю информацию, относящуюся к отдельным объектам.

Что-то вроде: SELECT * FROM IRessource i JOIN Room r ON i.id == r.id

Однако, вы будете часто раз считаю, что если вы используете Web API контроллер, если вы просто вытащить весь Room ПОКО, вы получите все свои свойства сразу без объединения вообще!


В моем опыте, я также обнаружил, что, как правило, все идет гладко, если вы не использовать интерфейсы или абстрактные классы, потому что если вы делаете, вы должны сделать объекты передачи данных (DTO) в иногда, поскольку вы не можете создавать объекты этих типов. Вещи могут стать немного грязными - особенно если вы не уверены, что именно вы делаете.Чтобы помочь вам разобраться, подумайте о контроллере, с которым вы хотите перейти в родовом IRressource, - он попытается преобразовать эти объекты, когда он получит их, в тот, который не может быть создан. Вот досада! Таким образом, простое решение состоит в том, чтобы сделать как базовый класс, так и унаследованные классы нормальными классами.

+0

Это похоже на путь! Я пробую это прямо сейчас! –

+0

Опубликуйте обновление, если у вас возникли проблемы или замешательство. Еще одна вещь, которую следует отметить, заключается в том, что подклассы наследуют ключ от родителя, что не показано в исходном коде, но оно находится в ссылке TPT. –

+0

Хм .. он не работает с интерфейсом, который я считаю приемлемым. Попробуйте это с абстрактными классами. –

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