Entity Framework: Является ли Table Per Hierarchy подходящим шаблоном наследования для этой ситуации?

Представьте, что у меня есть иерархия объектов, которые я хочу сохранить в своем хранилище данных Entity Framework 4.1. Я создаю их, используя Code First. Они выглядят так:

BasicState
  has many -> StatefulEntities
  has a -> CreationDate

ReceivedState 
  has a -> EntityLocation

ApprovedState
  has a -> EntityLocation

OrderedState
  has a -> Order

DispatchedState 
  has a -> Order
  has a -> DispatchNumber

BasicState является родителем для всех других состояний, все остальное разделяет эти два поля / отношения.

Моя первоначальная мысль и способ, которым я это реализовал, состояла в том, чтобы использовать наследование Table Per Hierarchy, потому что казалось, что я мог просто наследовать от BasicState и мои другие государства участвуют в этих общих свойствах.

Однако это вызвало проблему, потому что, когда разные состояния совместно используют поле, базовая модель данных не имеет, поэтому, например, моя база данных будет иметь EntityLocation_Id от одного из ReceivedState а также ApprovedState а также EntityLocation_Id1 с другой. Это затрудняет создание тестовых данных, поскольку вы не знаете, какие поля принадлежат каким моделям. Я спрашивал об этом ранее.

Решение, которое я выбрал, заключалось в следующем:

public abstract class BaseState
{
     public DateTime CreatedDate { get; set; }

     public ICollection<StatefulEntity> StatefulEntities{get;set;}
}


public abstract class LocationState : BaseState
{
     public Location EntityLocation { get; set; }
}

public class ReceivedState : LocationState
{

}

public class ApprovedState : LocationState
{

}

Это работало частично, однако, хотя он создал один EntityLocation_Id это все еще создало два Order_Ids за OrderedState а также DispatchedStateдаже если они ведут себя одинаково и реализации не различимы.

После того, как это почти наполовину решено, я столкнулся с другой проблемой, которая заставляет меня задать этот вопрос:

Учитывая, что я отношения между BasicState а также StatefulEntities много ко многим в обоих направлениях, я должен быть в состоянии найти детали заказа от OrderedStates принадлежность к StatefulEntity,

Проблема в том, что хотя это довольно легко представить в SQL, наследование означает, что Entity Framework не знает, является ли BasicState является OrderedState так что, похоже, нет никакого способа сделать одну поездку в базу данных, чтобы включить OrderedState.Order,

Так что я не могу сделать что-то вроде этого:

statefulEntityRepository.Get().Where( x => x.Id == 1 ).Include( x => x.BasicStates ).Include( x.BasicStates.Order );

Очевидно, это не тот код, который будет работать, но он показывает, в чем проблема - Орден принадлежит только определенным подтипам BasicState и поэтому EF не будет предварительно загружать его, даже если я использую какое-то приведение.

Если я попробую проецирование, я получу что-то вроде этого:

statefulEntityRepository.Get().Select( x=> new { 
             StatefulEntity = x,
             EntityLocation = ( from state in x.BaseStates where state is ReceivedState select state.EntityLocation )
          }

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

Я дошел до попытки определить мой базовый класс и наследники таким образом:

public abstract class BaseState
{
     public DateTime CreatedDate { get; set; }

     public ICollection<StatefulEntity> StatefulEntities{get;set;}

     public long EntitytLocationId { get; set; }
}


public abstract class LocationState : BaseState
{
     [Column(name="EntityLocationId")]
     public Location EntityLocation { get; set; }
}

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

Редактировать: я думаю, что у меня есть немного больше понимания этого сейчас - от попытки установить ForeignKey на дальнем конце этого отношения (то есть отношения между Location и LocationState) это выглядит так, как будто обратная коллекция в Order или Location может Не говорите о свойстве, которое отсутствует в базовом объекте, поэтому мне придется использовать версию выше. Это создает новую проблему в том, как я управляю делами, у которых нет EntityLocationId или OrderId - если я сделаю эти поля обнуляемыми, то возникает ошибка, что ссылочные поля не могут быть пустыми при создании базы данных, и по умолчанию нет способа установить начальное значение для поле в первом коде.

Кто-нибудь может порекомендовать лучший способ представления этого типа модели, которая будет работать с Entity Framework?

0 ответов

Другие вопросы по тегам