2011-07-21 37 views
5

我已经创建了一个使用实体框架从我的数据库返回数据的存储库,我需要将这些数据提供给我的视图,但在此之前我需要将这些对象转换为我的视图领域模型。MVC仓库 - 域模型vs实体模型

我的模式是这样的:

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 

我有一个返回项目资源库:

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

和控制器动作:

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

    return View(project); 
} 

当我尝试并POST这些数据时,这似乎不起作用。当它试图重建ProjectResources集合时,我得到了一个EntityCollection已经初始化的错误。

我认为这是聪明创建一个域模型就是有点简单:

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 - >资源跳跃。 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的东西在控制器中处理的,那会是什么样子?

回答

5

我自己的看法是,你不应该返回任何东西到你的控制器或依赖于你的仓库实现的视图。

如果您将EF与POCO Generator一起使用,那么将这些类用于您的域模型是合理的,因为它们独立于EF实现(您可以替换EF并保留POCO)。

但是,如果您使用EF与其EntityObjects,我相信你应该转换到您的域模型。如果您的数据访问被封装在内部使用存储库模式的WCF服务中,我不会过多担心从存储库中返回EntityObjects。但是如果您直接从MVC使用存储库,请使用域模型作为存储库的接口。

+0

所以你说我的仓库应该返回域模型而不是实体模型? – Dismissile

+0

如果您的存储库未封装在单独的服务中,是的。请下来选民请解释一下 –

-1

你所描述的正是我多年来一直在做的事,追随着n层应用程序设计。

因为您的数据并不总是以与您的域相同的方式组织。在SQL中发生的事情在您的域中并不总是一样的,正如您在这里遇到的一样。

通常,我的域名知道存储库的外观,并具有用于转换的方法。我的用户界面/视图知道该域的外观,并有检索该数据(在控制器中)的方法。

这么简单的答案,我会说,在中间的东西(你的业务层),并让你的控制器可以使用这些方法来接收这些数据。

+0

。 – Jay

3

我们往往总是使用一个ViewModel作为“中间阶级”,并映射到和使用实际模型...

Automapper

......或者......

ValueInjecter

如果你愿意,你的ViewModel可以在结构上相当独立于你的模型。