В настоящее время я разрабатываю проект в MVC 3. Я отделил свои проблемы, поэтому есть такие проекты, как Core, Repository, UI, Services и т.д. Я реализую репозиторий, UnitOfWork и, самое главное, шаблон состояния.
Я использую Entity Framework 4.3 для сохранения своих данных, и я столкнулся с довольно неприятной ситуацией, связанной с сохранением текущего состояния. Ниже приведены некоторые примеры классов:
public class Request
{
public int RequestId { get; set; }
public State CurrentState { get; set; }
}
public abstract class State
{
[Key]
public string Name {get; set;}
public virtual void OpenRequest(Request request)
{}
public virtual void CloseRequest(Request request)
{}
}
public class RequestIsOpenState : State
{
public RequestIsOpenState()
{
this.Name = "Open";
}
public override void CloseRequest(Request request)
{
request.CurrentState = new RequstIsClosedState();
}
}
public class RequestIsClosedState : State
{
public RequestIsClosedState()
{
this.Name = "Closed";
}
public override void OpenRequest(Request request)
{
request.CurrentState = new RequstIsOpenState();
}
}
Используя приведенный выше пример, я получаю исключение нарушения первичного ключа, потому что он пытается создать новое состояние в таблице States.
Поскольку изменение состояния выполняется на уровне домена, я не могу просто "получить" состояние из репозитория и установить его с помощью внешнего ключа, выполнив что-то вроде этого:
Request request = unitOfWork.RequestRepository.Find(1);
request.CurrentState = unitOfWork.StateRepository.Find("Closed");
Я знаю, что у меня есть возможность не сопоставлять свойство состояния и сохранять свойство строки в классе запроса, а затем преобразовывать их обратно и вперед через factory в get и задавать, когда объект гидратируется ( см. этот ответ).
Все, что я хочу сделать, это сохранить класс состояния, поэтому, когда запрос будет возвращен, я могу немедленно получить доступ к методам состояния, не загружая элементы EF, загрязняющие мой доменный уровень, чтобы справиться с одной проблемой сохранения. Другим преимуществом этого является то, что это дает мне дополнительный бонус наличия таблицы в SQL для запроса от известных состояний.