将一个字段合二为一 table 并在视图中显示两者的结果?

Sum one field in one table and display the result from both in the view?

我有两个 table。一位有 posts,一位有选票。 table 都包含 postId (PK/FK)。我想将所有 post 的投票 table 分组,然后对每个 post 的 post 投票求和。然后在视图中我想要显示 post 和每个 post 的总票数。如果没有投票,post我想使用 0 作为默认值。

例如,如果我在 post table

中有此数据
+--------+---------+-------------+---------+
| PostId | Message | MessageDate | User_Id |
+--------+---------+-------------+---------+
| 1      | test 1  | 2016-01-01  | 1       |
+--------+---------+-------------+---------+
| 2      | test 2  | 2016-01-01  | 1       |
+--------+---------+-------------+---------+
| 3      | test 3  | 2016-01-01  | 1       |
+--------+---------+-------------+---------+

票数table

+--------+------------+---------+
| PostId | PostVote   | User_Id |
+--------+------------+---------+
| 1      | 1          | 1       |
+--------+------------+---------+
| 1      | 1          | 2       |
+--------+------------+---------+
| 2      | -1         | 1       |
+--------+------------+---------+

我想在视图中显示这个

Message  Vote
Test 1 -  2
Test 2 -  -1
Test 3 -  0

由于两个用户对 postId 投了 1 (1+1) 票,一个用户对 postId 2 投了 -1 并且没有对 PostId 3 投票(因此它应该是默认的0 在视图中)。

这是我的post模型

public class Post
{
    public Post()
    {
        this.Vote = new HashSet<Vote>();
    }

    public int PostId { get; set; }
    public string Message { get; set; }
    public DateTime MessageDate { get; set; }

    public virtual ApplicationUser User { get; set; }
    public virtual ICollection<Vote> Vote { get; set; }
}

这是我的投票模型

public class Vote
{
    [Key, Column(Order = 0)]
    public string ApplicationUserID { get; set; }

    [Key, Column(Order = 1)]
    public int PostId { get; set; }

    public virtual Post Post { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; }

    public int PostVote { get; set; }
}

我想我应该使用 Viewmodel 并创建这个

public class ListPostsViewModel
{
    public List<Post> Posts { get; set; }
    public List<Vote> Votes { get; set; }
}

然后我尝试在控制器中使用我的 ViewModel,根据 postId 对投票求和并合并 posts 和投票到视图。这是我现在的控制器。

var posts = db.Posts.OrderByDescending(p => p.PostId).ToList();

var postsVM = posts.Select(post => new ListPostsViewModel { Posts = posts});

var votes = db.Votes.GroupBy(u => u.PostId)
                .Select(v =>
                                new
                                {
                                    PostId = v.Key,
                                    TotalVotes = v.Sum(w => w.PostVote) //sum the votes
                                }).ToList();

var votesVM = posts.Select(post => new ListPostsViewModel { Votes = votes });

我在 votesVM 上收到这个错误

Cannot implicitly convert type 'System.Collections.Generic.List<AnonymousType#1>' to 'System.Collections.Generic.List<FreePost.Models.Vote>'

异常是因为您的 var votes = ... 查询正在生成匿名对象的集合,然后您尝试将其分配给 属性,即 List<Vote>(它们不相同类型)。

为了生成你想要的视图,你的视图模型需要

public class PostVoteVM
{
    public string Message { get; set; }
    public int TotalVotes { get; set; }
}

以便您可以在视图中使用

@model IEnumerable<PostVoteVM>
<table>
    @foreach(var post in Model)
    {
        <tr>
            <td>@post.Message</td>
            <td>@post.TotalVotes </td>
        </tr>
    }
</table>

正因为您的模型具有正确的导航属性,您只需要一个查询,并将查询结果投影到视图模型的集合中

var model = db.Posts.Include(p => p.Vote) // Include may not be required
    .OrderByDescending(p => p.PostId)
    .Select(p => new PostVoteVM()
    {
        Message = p.Message,
        TotalVotes = p.Vote.Sum(v => v.PostVote)
    });
return View(model);