在一个表中求和一个字段并在视图中显示两者的结果?

时间:2016-10-17 12:56:44

标签: c# asp.net-mvc asp.net-mvc-4 viewmodel

我有两张桌子。一个有帖子,另一个有投票。两个表都包含postId(PK / FK)。我想将所有帖子分组投票表,并为每个帖子总结postVote。然后在我想要的视图中显示每个帖子的帖子和总投票。如果对该帖子没有投票我想要使用默认值为0。

如果我在帖子表中有这些数据

+--------+---------+-------------+---------+
| 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       |
+--------+---------+-------------+---------+

投票表

+--------+------------+---------+
| 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)。

这是我的帖子模型

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对投票进行求和,并将帖子和投票合并到视图中。这是我的控制器。

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上得到了这个错误

  

无法隐式转换类型   'System.Collections.Generic.List&LT; AnonymousType#1&GT;'至   'System.Collections.Generic.List&LT; FreePost.Models.Vote&GT;'

1 个答案:

答案 0 :(得分:0)

引发异常是因为您的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);