【问题标题】:Fetching a single post along with all comments relating to that post in Asp.net mvc4在 Asp.net mvc4 中获取单个帖子以及与该帖子相关的所有评论
【发布时间】:2014-12-08 13:34:44
【问题描述】:

大家好, 我目前面临一个查询问题,该查询使用查询字符串中的 id 参数从数据库中获取单个帖子并检索属于帖子的所有 cmets。到目前为止,我知道我想要一个帖子,因此我的视图将不包含 IEnumerable 接口,因为在我的查询中我使用 .single()。但是,由于我要从数据库中获取 cmets 列表,而不仅仅是一条评论,我知道这将是 IEnumerable。我的问题是如何组合这两个界面,以便我可以显示该单个帖子和属于它的所有 cmets。

 public class ReadPostsVM
{
    public string PostTitle { get; set; }

    public string PostContent { get; set; }

    public string PostAuthor { get; set; }

    public DateTime PostDate { get; set; }

    public string Comment { get; set; }

    public string CommentAuthor { get; set; }

    public DateTime CommentDate { get; set; }


}

这是我在控制器中尝试过的

public ActionResult ReadPost(int id)
{
    var query = from p in db.Posts.Where(p => p.PostId == id)
                from c in db.Replies.Where(c => c.PostId == id)
                join u in db.UserProfiles
                on p.AuthorId equals u.UserId
                where p.PostId == id
                select new ReadPostsVM()
                {
                    PostTitle = p.PostTitle,
                    PostContent = p.PostContent,
                    PostDate = p.DateCreated,
                    PostAuthor = u.UserName,
                    Comment = c.Reply1,
                    CommentAuthor = u.UserName,
                    CommentDate = c.ReplyDate
                };

    var query = from p in db.Posts
                join u in db.UserProfiles
                on p.AuthorId equals u.UserId
                where p.PostId == id
                select new ReadPostsVM()
                {
                    PostTitle = p.PostTitle,
                    PostContent = p.PostContent,
                    PostDate = p.DateCreated,
                    PostAuthor = u.UserName,

                };

    return View(query.Single());


}

然而在我看来

@model IEnumerable<Blogger.ViewModels.ReadPostsVM>

还有一个 foreach 循环,它给了我一个错误提示

Sequence does not contain any element

我认为我有另一个选择是在下面获取这个

public ActionResult ReadPost(int id)
    {

        var query = from p in db.Posts
                    join u in db.UserProfiles
                    on p.AuthorId equals u.UserId
                    where p.PostId == id
                    select new ReadPostsVM()
                    {
                        PostTitle = p.PostTitle,
                        PostContent = p.PostContent,
                        PostDate = p.DateCreated,
                        PostAuthor = u.UserName,

                    };

        return View(query.Single());


    }

使用返回单个帖子来获取该单个帖子,然后也许我可以使用部分视图来显示 cmets。

@model Blogger.ViewModels.ReadPostsVM

请帮助我如何实现这一目标。如果我要使用部分视图,我如何使该部分视图根据 url 中的参数获取 cmets,因为我将不得不使用 id 参数调用一个操作,但我没有任何指向该页面的链接,而且我不要认为那样有意义。我希望我的问题有意义吗?请帮忙!

为了显示 Posts 实体和 cmets 实体之间的关系,我在下面添加了 Posts.cs 类和 Replies.cs 类

public partial class Post
{
    public Post()
    {
        this.Replies = new HashSet<Reply>();
    }

    public int PostId { get; set; }
    public string PostTitle { get; set; }
    public string PostContent { get; set; }
    public int AuthorId { get; set; }
    public int CategoryId { get; set; }
    public System.DateTime DateCreated { get; set; }

    public virtual Category Category { get; set; }
    public virtual UserProfile UserProfile { get; set; }
    public virtual ICollection<Reply> Replies { get; set; }
}



 public partial class Reply
    {
        public int ReplyId { get; set; }
        public string Reply1 { get; set; }
        public System.DateTime ReplyDate { get; set; }
        public int AuthorId { get; set; }
        public int PostId { get; set; }
        public int CategoryId { get; set; }

        public virtual Category Category { get; set; }
        public virtual Post Post { get; set; }
        public virtual UserProfile UserProfile { get; set; }
    }

【问题讨论】:

  • 我建议您使用 LINQ 来简化查询。一旦正确设置了一对多关系,就可以直接显示相关的 cmets。例如在您的视图中使用 Razor 语法:@foreach (var item in Model.cmets) { // display comment content } 其中模型是您的帖子。
  • Post(实体)类是什么样子的?它与评论实体有一对多的关系吗?
  • 无需使用局部视图来显示 cmets,尽管这有助于保持代码整洁。这提供了设置一对多的快速概览:stackoverflow.com/questions/16927018/…
  • @Sam Post 实体与 Comment 实体具有一对多的关系。我已经更新了我上面的问题。
  • 谢谢,希望我的简短回答对您有所帮助。主要问题似乎是您的 ReadPostsVM 只有一个指向单个评论的链接,而不是一个 cmets 列表,您需要这些链接才能遍历它们。

标签: c# asp.net-mvc


【解决方案1】:

您需要更改视图模型,以便 Post 视图模型包含评论集合

查看模型

public class CommentVM
{
  public string Comment { get; set; }
  public string CommentAuthor { get; set; }
  public DateTime CommentDate { get; set; }
}

public class PostVM
{
  public string PostTitle { get; set; }
  public string PostContent { get; set; }
  public string PostAuthor { get; set; }
  public DateTime PostDate { get; set; }
  List<CommentVM> Comments { get; set; }
}

控制器(我将把它留给你隐藏到 LINQ To SQL)

public ActionResult ReadPost(int id)
{
  Post post = db.Posts.Find(id);
  PostVM model = new PostVM()
  {
    PostTitle = post.PostTitle,
    PostContent = post.PostContent,
    PostAuthor = post.UserProfile.UserName,
    PostDate = post.DateCreated,
    Comments = post.Replies.Select(r => new CommentVM()
    {
      Comment = r.Reply1,
      CommentAuthor = r.UserProfile.UserName,
      CommentDate = r.ReplyDate
    })
  };
  return View(model);
}

查看

@model PostVM
...
@DisplayFor(m => m.PostTitle)
...
@DisplayFor(m => m.PostDate )

@foreach(var comment in Model.Comments)
{
  @DisplayFor(comment.Comment)
  ...
  @DisplayFor(comment.CommentDate)
}

【讨论】:

  • 我从来不知道我可以像这样混合视图模型,上帝保佑你这么多,我呼吁你,你注意到了。会尝试上述解决方案并回复您。
【解决方案2】:

您可以查看类似 automapper 的工具来简化您的映射。否则,为了简单起见,在您的视图模型中有类似的内容:

public IEnumerable<comment> comments { get; set; }

然后有一个正确填充它的方法:

 select new ReadPostsVM()
                    {
                        PostTitle = p.PostTitle,
                        PostContent = p.PostContent,
                        PostDate = p.DateCreated,
                        PostAuthor = u.UserName,
                        PostReplies = p.Replies
                    };

然后,您将能够通过循环访问 PostReplies 来访问视图中的回复信息:

@foreach (var reply in Model.PostReplies)
 {
<div>reply.Reply1</div>
<div>reply.UserProfile.name</div>
}

【讨论】:

  • 但这只会获取 cmets 而不是 viewModel 中的其他属性,例如 CommentAuthor 和 CommentDate。
  • 不应该这样。您应该能够遍历 PostComments,例如使用 razor,然后访问其他属性。也许,如果您打开了延迟加载,那么您需要类似: PostComments = p.cmets.Include(CommentAuthor)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-14
  • 1970-01-01
  • 2016-06-30
相关资源
最近更新 更多