c# - Entity Framework 预加载 - 将数据传递给 ViewModel

标签 c# asp.net-mvc visual-studio-2015 linq-to-entities entity-framework-core

在我的 ASP.NET MVC Core 应用程序中,通过下面所示的操作方法,我将博客数据及其相关数据从 Posts 表传递到 View ,作为 return View(await _context.Blogs.Include(p => p.Posts).ToListAsync()); 由于我从两个表传递数据,因此我需要使用如下所示的 ViewModel。 问题:如何使用 ViewModel 从 Controller Action 方法传递相关数据 Test() 查看如下所示?

在下面的代码中,我得到了明显的错误:

InvalidOperationException: The model item passed into the ViewDataDictionary is of type 'System.Collections.Generic.List'1[ASP_Core_Blogs.Models.Blog]', but this ViewDataDictionary instance requires a model item of type 'System.Collections.Generic.IList'1[ASP_Core_Blogs.Models.BlogPostViewModels.BlogsWithRelatedPostsViewModel]'.

型号:

public class BloggingContext : DbContext
{
    public BloggingContext(DbContextOptions<BloggingContext> options)
        : base(options)
    { }

    public DbSet<Blog> Blogs { get; set; }
    public DbSet<Post> Posts { get; set; }
}

public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }

    public List<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public int PostYear { get; set; }
    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

Controller :

[HttpGet]
public async Task<IActionResult> Test(string returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    return View(await _context.Blogs.Include(p => p.Posts).ToListAsync());
}

ViewModel:

public class BlogsWithRelatedPostsViewModel
{
    public int BlogID { get; set; }
    public int PostID { get; set; }
    public string Url { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }
    public int PostYear { get; set; }
}

查看:

@model IList<ASP_Core_Blogs.Models.BlogPostViewModels.BlogsWithRelatedPostsViewModel>

<div class="row">
    <div class="col-md-12">
        <form asp-controller="DbRelated" asp-action="EnterGrantNumbers" asp-route-returnurl="@ViewData["ReturnUrl"]" method="post">
            <table class="table">
                <thead>
                    <tr>
                        <th></th>
                        <th></th>
                        <th>Url</th>
                        <th>Title</th>
                        <th>Content</th>
                    </tr>
                </thead>
                <tbody>
                    @for (int t = 0; t < Model.Count; t++)
                    {
                        <tr>
                            <td><input type="hidden" asp-for="@Model[t].BlogID" /></td>
                            <td><input type="hidden" asp-for="@Model[t].PostID" /></td>
                            <td>
                                <input type="text" asp-for="@Model[t].Url" style="border:0;" readonly /> <!--Not using /*Html.DisplayFor(modelItem => Model[t].Url)*/ since it does not submit stateName on Post. Not using <label asp-for=.....> since Bootstrap bold the text of <label> tag-->
                            </td>
                            <td>
                                <input asp-for="@Model[t].Title" />
                            </td>
                            <td>
                                <input asp-for="@Model[t].Content" />
                            </td>
                        </tr>
                    }
                </tbody>
            </table>
            <button type="submit" class="btn btn-default">Save</button>
        </form>
    </div>
</div>

最佳答案

您需要使用 BlogsWithRelatedPostsViewModel 来投影您的查询类:

     return View( _context.Blogs
                          .Include(p => p.Posts)
                          .SelectMany(e=> e.Posts.Select(p=> new BlogsWithRelatedPostsViewModel
                                                             {
                                                              BlogId= e.BlogId,
                                                              PostId=p.PostId,
                                                              Url=e.Url,
                                                              ...
                                                             })
                          .ToList()); 

SelectMany扩展方法允许您展平 e.Posts 中的每个投影成一个序列,所以最后你会得到 List<BlogsWithRelatedPostsViewModel>

关于c# - Entity Framework 预加载 - 将数据传递给 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39458401/

相关文章:

visual-studio-2015 - 我们可以将 WORD 加载项发布到 Windows 10 应用商店吗?

visual-studio-2015 - VS 2015 中的 ASP.NET MVC6 引用

c# - 在 Facebook Messenger 中分享按钮

c# - linq 不区分大小写(没有 toUpper 或 toLower)

c# - 如何将动态对象传递给 HtmlHelper.Editor()?

javascript - 如何从ajax调用MVC Controller 获取数据?

javascript - 使用 Visual Studio 2015 在 Apache Cordova 中打开缺少 exec :SQLitePlugin.

c# - 如何从调用栈中反射(reflect)C#显式接口(interface)实现?

c# - VS2010中文件不存在异常

javascript - 在亚马逊S3上上传大小超过3GB的文件