Хранилище MVC - модель предметной области против модели сущностей - PullRequest
5 голосов
/ 21 июля 2011

Я создал репозиторий, который возвращает данные из моей базы данных с использованием Entity Framework, и мне нужно предоставить эти данные моему представлению, но прежде чем я это сделаю, мне нужно преобразовать эти объекты в мою модель домена.

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

TABLE Project
    Id INT PRIMARY KEY
    Name NVARCHAR(100)

TABLE Resource
    Id INT PRIMARY KEY
    FirstName NVARCHAR(100)
    LastName NVARCHAR(100)

TABLE ProjectResources
    Project_Id INT PRIMARY KEY   -- links to the Project table
    Resource_Id INT PRIMARY KEY  -- links to the Resource table

Я сгенерировал модель сущности, которая в итоге выглядела так:

Project
|
---->ProjectResources
     |
     ---->Resource

У меня есть репозиторий, который возвращает Project:

public interface IProjectRepository
{
    Project GetProject(int id);
}

И действие контроллера:

public ActionResult Edit(int id)
{
    Project project = projectRepository.GetProject(id);

    return View(project);
}

Это, кажется, не очень хорошо работает, когда я пытаюсь POST эти данные.Я получал уже инициализированную EntityCollection ошибку при попытке восстановить коллекцию ProjectResources.

Я думаю, что разумнее создать модель домена, которая немного проще:

public class ProjectEdit
{
    public string ProjectName { get; set; }
    public List<ProjectResource> Resources { get; set; }
}

public class ProjectResource
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Этокажется немного приятнее, так как у меня также нет промежуточного ProjectResources -> Resource jump.ProjectResource будет иметь поля, которые мне нужны.Вместо того, чтобы делать что-то вроде:

@foreach( var resource in Model.ProjectResources ) {
    @Html.DisplayFor(m => m.Resource.FirstName)
}

Я могу сделать:

@foreach( var resoure in Model.Resources ) {
    @Html.DisplayFor(m => resource.FirstName);
}

Мой вопрос заключается в следующем Должен ли я возвращать модель моего домена из своего хранилища илиэто должно быть обработано контроллером или каким-либо другим классом в середине?Если он обрабатывается в контроллере чем-то, что отображает мой проект в ProjectEdit, как бы это выглядело?

Ответы [ 3 ]

5 голосов
/ 21 июля 2011

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

Если вы используете EF с генератором POCO, разумноиспользуйте эти классы для вашей доменной модели, потому что они не зависят от реализации EF (вы можете заменить EF и сохранить POCO).

Но если вы используете EF с его объектами EntityObjects, я считаю, что вам следует преобразовать вмодель вашего домена.Если бы ваш доступ к данным был инкапсулирован в службу WCF, которая использовала шаблон репозитория для внутреннего использования, я бы не стал так сильно беспокоиться о возврате объектов EntityObject из репозитория.Но если вы используете репозиторий напрямую из MVC, используйте модель домена в качестве интерфейса к репозиторию.

3 голосов
/ 21 июля 2011

Мы склонны всегда использовать ViewModel в качестве «класса посередине» и отображать в и из фактической Модели, используя ...

Automapper

... или ...

ValueInjecter

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

0 голосов
/ 21 июля 2011

То, что вы описываете, это то, чем я занимаюсь годами, пытаясь следовать n-уровневому дизайну приложений.

Поскольку ваши данные не всегда будут организованы так же, как ваш домен.Что делает, поскольку в SQL не всегда то же самое в вашем домене, как вы столкнулись здесь.

Обычно мой домен знает, как выглядит хранилище, и имеет методы для конвертации в и из.Мой интерфейс / представления знают, как выглядит домен, и имеют методы для извлечения этих данных (которые поступают в контроллер).

Итак, я бы сказал, что вкратце, что-то посередине (уровень вашего бизнеса), и у вас есть методы, используемые вашими контроллерами для получения этих данных.

...