微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ASP.NET MVC 父子视图模型和实体框架

如何解决ASP.NET MVC 父子视图模型和实体框架

这是我的代码

家长:

public class Parent
{
    [Key]
    public int Id { get; set; }

    [required]
    [MaxLength(50),MinLength(3)]
    [display(Name = "Parent Name")]
    public string Name { get; set; }

    [required]
    [MaxLength(50),MinLength(3)]
    [display(Name = "Parent Surname")]
    public string Surname { get; set; }

    public List<Child> Children { get; set; } = new List<Child>();
}

孩子:

public class Child
{
    [Key]
    public int Id { get; set; }

    [required]
    [MaxLength(50),MinLength(3)]
    [display(Name = "Child Name")]
    public string Name { get; set; }

    [required]
    [MaxLength(50),MinLength(3)]
    [display(Name = "Child Surname")]
    public string Surname { get; set; }

    [required]
    [display(Name = "Parent")]
    public int ParentId { get; set; }

    [ForeignKey("ParentId")]
    public virtual Parent Parent { get; set; }
}

视图模型:

public class ParentChildviewmodel
{
    public Parent Parent { get; set; }
    public IEnumerable<Child> Children { get; set; }
}

控制器:

public class DemoController : Controller
{
    private readonly ApplicationDbContext _db;
    public DemoController(ApplicationDbContext db)
    {
        _db = db;
    }
    public async Task<IActionResult> Index(int id)
    {
        var parent = await _db.Parents.AsNoTracking().FirstOrDefaultAsync(i => i.Id == id);

        var child = await _db.Children.AsNoTracking().Where(i => i.ParentId == id).ToListAsync();
        
        var model = new ParentChildviewmodel
        {
            Parent = parent,Children = child
        };

        return View(model);
    }
}

查看:

@model TwoModels.Models.ParentChildviewmodel
<h2> Demo Table Parent</h2>
<table style="border:solid 2px;">
    <tr>
        <td>
            Parent Name:
        </td>
        <td>
            @Html.displayFor(m => m.Parent.Name) <br />
        </td>
    </tr>
    <tr>
        <td>
            Parent Surname:
        </td>
        <td>
            @Html.displayFor(m => m.Parent.Surname) <br />
        </td>
    </tr>
</table>
<h2>Demo Table Child</h2>
<table style="border:solid 2px;">
    @foreach (var item in Model.Children)
    {
        <tr>
            <td>
                Child Name:
            </td>
            <td>
                @Html.displayFor(modelItem => item.Name) <br />
            </td>
        </tr>
        <tr>
            <td>
                Child Surname:
            </td>
            <td>
                @Html.displayFor(modelItem => item.Surname) <br />
            </td>
        </tr>
    }
</table>

代码很容易理解,我使用: _db.Parents.AsNoTracking().FirstOrDefaultAsync(i => i.Id == id) 为 Parent (我不想要一个列表,而只想要 First) 和: _db.Children.AsNoTracking().Where(i => i.ParentId == id).ToListAsync()(这是一个列表)

但是这种方式对数据库的请求是两次。所以,我想修改代码,保留 viewmodel 的使用,但只访问数据库一次。我想到了什么:

_db.Parents.AsNoTracking().Include(c=>c.Children).Where(i => i.Id == id).ToListAsync();

如何更改我的控制器代码和视图?

解决方法

您的操作可能是这样的:

public async Task<IActionResult> Index(int id)
    {
        var item = await _db.Parents.AsNoTracking().
.Include(c=>c.Children)
.Where(i => i.Id == id).
FirstOrDefaultAsync();

           var model = new ParentChildViewModel
        {
            Parent = item,Children = item.Children
        };
         item.Children=null; // only if you want to use view model alone.
        return View(model);
    }

并从 Children 属性中删除 new List() 。应该是这样的:

public List<Child> Children { get; set; }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。