0

我正在尝试做一些我感觉像是一项小任务的事情,但我想不出一个简单的方法来做到这一点。对于一个简单的任务,我所有这样做的方法都变得非常复杂。

我有这些模型:

public class Blog
{
    public int Id { get; set; }
    public String Name { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public String Name { get; set; }
    public int BlogId { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
}

public class Comment
{
    public int Id { get; set; }
    public String CommentText { get; set; }
    public int PostId { get; set; }
    public int UserProfileUserId { get; set; }
}

public class UserProfile
{
    public int UserId { get; set; }
    public string UserName { get; set; }
    public String FirstName { get; set; }
    public String LastName { get; set; }
}

在添加的评论部分视图中,我想显示发表评论的用户的完整用户名。如果我只是在我的视图和部分视图中使用我的基类,我会得到我需要的一切,除了添加评论的完整用户名。到目前为止,我已经想到了以下方法:

ViewModels - 这将为我的每个类创建一个 ViewModel,然后在我的控制器中手动填充/映射它们。

视图中的代码 - 我有 UserProfileUserId,所以我可以从视图中询问存储库,但这会杀死 MVC 中的 MVC,所以我不想这样做。

实际上将 UserProfileFirstName 和 UserProfileLastName 作为外键添加到 Comment Class - 这感觉就像用视图特定数据填充数据库。它不属于关系数据库。

使用常规 SQL 并查询数据库——仅仅因为我知道 SQL,这可能是一种方法。但话又说回来,我在 MVC 中杀死了 MVC。

我该怎么做?我愚蠢的被忽视的选择在哪里?我搜索了很多但找不到答案,但这可能与我还不知道所有技术术语有关。抱歉,如果之前回答了 1000 次。

4

1 回答 1

2

理想情况下,我会更改我的域模型以包含Author类型属性UserProfile并使用 JOIN(注释表和用户表)加载该数据

public class Comment
{
    public int Id { get; set; }
    public String CommentText { get; set; }
    public int PostId { get; set; }
    public UserProfile Author { get; set; }
}

编辑: 根据评论中的问题

我将这样做。

我的存储库方法将有这些方法

List<Comment> GetCommentsForPost(int postId);
BlogPost GetPost(int postId);

我会用 ViewModel 来表示这样的单个博客文章

public class PostViewModel
{
   public int PostID { set;get;}
   public string PostText { set;get;}
   public string AuthorDisplayName { set;get;}
   public List<CommentViewModel> Comments { set;get;}

   public PostViewModel()
   {
      Comments=new List<CommentViewModel>();
   }
}
public class CommentViewModel
{
  public int CommentID {set;get;}
  public string Text { set;get;}
  public string AuthorDisplayName { set;get;}  
}

现在在您的GET操作中,从您的存储库中获取数据并将其映射到 ViewModel 并将其发送到视图

public ActionResult ViewPost(int id)
{

  var post=repositary.GetPost(id);
  if(post!=null)
  {
    PostViewModel vm=new PostViewModel { PostID=id };
    vm.PostText=post.Name;
    var comments=repo.GetCommentsForPost(id);
    foreach(var item in comments)
    {
      vm.Comments.Add(new CommentViewModel { CommentID=item.Id, 
                              AuthorDisplayName=item.Author.FirstName});
    }
    return View(vm);
  }
  return View("NotFound");
}

现在您的视图将被强输入到 ThePostViewModel

@model PostViewModel

<h2>@Model.PostText</h2>
@Html.Partial("Comments",Model.Comments)

并且您的局部视图(Comments.cshtml)将被强类型化为一个集合CommentViewModel

@model List<CommentViewModel>
@foreach(var item in Model)
{
  <div>
     @item.Text
     <p>Written by @item.AuthorDisplayName</p>
  </div>
}

现在我们的视图不直接依赖于领域模型。如果我们需要,这允许我们明天从另一个来源获取数据(例如:从 Web 服务获取评论)并简单地映射到我们的视图模型。

一些笔记

不要在视图中添加太多代码。让我们尽可能保持纯 HTML。没有直接来自视图的数据访问调用!

为了您的理解,我手动将域模型映射到视图模型。您可以使用Automapper之类的映射库来执行此操作。您也可以将我们在 GET 操作方法中的部分代码移动到另一个服务层,以便可以在多个地方重用它。

于 2012-12-15T22:55:01.587 回答