C# 如何在一个视图中实现两个模型的编辑方法

C# 如何在一个视图中实现两个模型的编辑方法,c#,asp.net,asp.net-mvc,C#,Asp.net,Asp.net Mvc,我的主题的开始是 使用DropDownList不允许我编辑作者的姓名。。但这个解决方案真的很好 我需要编辑所有4个字段,如名称、标题、年份和价格 我尝试制作一些类似复合模型的东西: public class BookAuthorCompositeModel { public Author author { get; set; } public Book book { get; set; } } 更改我的获取方法: // GET: Books/Edit/5 publ

我的主题的开始是

使用DropDownList不允许我编辑作者的姓名。。但这个解决方案真的很好

我需要编辑所有4个字段,如名称、标题、年份和价格

我尝试制作一些类似复合模型的东西:

public class BookAuthorCompositeModel
{
    public Author author { get; set; }
    public Book book { get; set; }
}
更改我的获取方法:

// GET: Books/Edit/5       
public ActionResult Edit(int? id)
{
    if (id == null)
    {
        return HttpNotFound();
    }
    var compModel = new BookAuthorCompositeModel();
    compModel.book = dbBooks.Books.ToList().Where(a => a.Id == id).SingleOrDefault();
    compModel.author = dbBooks.Authors.ToList().Where(x => x.Id == id).SingleOrDefault();
    return View(bookEdit);
}
它显示了我所需要的一切(我点击“编辑”,查看有关姓名、头衔、年份和价格的信息)

我的看法是:

@model BookStorage.Models.BookAuthorCompositeModel

@{
    ViewBag.Title = "Edit";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h2>Edit</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Book</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.book.Id)

        <div class="form-group">
            @Html.LabelFor(model => model.author.AuthorName, "AuthorName", htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.author.AuthorName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.author.AuthorName, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.book.Title, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.book.Title, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.book.Title, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.book.YearPublish, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.book.YearPublish, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.book.YearPublish, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.book.Price, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.book.Price, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.book.Price, "", new { @class = "text-danger" })
            </div>
        </div>


        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Save" class="btn btn-default" />
            </div>
        </div>
    </div>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

dbBooks.SaveChanges();导致错误(Store update、insert或delete语句受意外行数(0)的影响)。我认为使用这种ViewModel有助于编辑所有行,但它不会将数据发送到DB,而且我无法理解错误所在。

如果我理解正确,您需要的是以相同的API方法更新上下文“Book”和上下文“Author”

为此,首先我将创建一个包含这两个对象的ViewModel,您已经拥有了:

public class BookAuthorCompositeModel
{
    public Author author { get; set; }
    public Book book { get; set; }
}
(为了验证的目的,可以修改它,也许可以创建新的验证对象。至少,我是这样做的。但让我们继续。)

现在,您需要在API调用中接收相同的ViewModel,然后对对象执行所需的操作。为此,我通常对我的上下文执行Get调用,获取要修改的对象。然后我可以自由地更新我的上下文:

[HttpPost]
    public ActionResult Edit(BookAuthorCompositeModel model)
    {
        ...
    }
要获取要修改的对象,取决于您使用的对象。简单的存储库模式、单元模式并不重要。当您获得图书条目时,只需修改它,使用更新函数,我相信它是dbBooks.BookContext.Update(Book),其中“Book”是变量。大概是这样的:

var book = dbBooks.BooksContext.Get(model.Book.BookId);

book.name = "New Name";

dbBooks.BooksContext.Update(book);
dbBooks.SaveChanges();
获取和更新(.Get()和.Update())的方法必须是您正在使用的模式中的方法,但这可能会对您有所帮助


祝你好运

如果我理解正确,您需要的是在同一API方法中更新上下文“Book”和上下文“Author”

为此,首先我将创建一个包含这两个对象的ViewModel,您已经拥有了:

public class BookAuthorCompositeModel
{
    public Author author { get; set; }
    public Book book { get; set; }
}
(为了验证的目的,可以修改它,也许可以创建新的验证对象。至少,我是这样做的。但让我们继续。)

现在,您需要在API调用中接收相同的ViewModel,然后对对象执行所需的操作。为此,我通常对我的上下文执行Get调用,获取要修改的对象。然后我可以自由地更新我的上下文:

[HttpPost]
    public ActionResult Edit(BookAuthorCompositeModel model)
    {
        ...
    }
要获取要修改的对象,取决于您使用的对象。简单的存储库模式、单元模式并不重要。当您获得图书条目时,只需修改它,使用更新函数,我相信它是dbBooks.BookContext.Update(Book),其中“Book”是变量。大概是这样的:

var book = dbBooks.BooksContext.Get(model.Book.BookId);

book.name = "New Name";

dbBooks.BooksContext.Update(book);
dbBooks.SaveChanges();
获取和更新(.Get()和.Update())的方法必须是您正在使用的模式中的方法,但这可能会对您有所帮助

祝你好运

FWIW,您永远不应该更新modelbinder从post数据创建的实体。始终从数据库中提取新的实体,并将发布的数据映射到该实体上。FWIW,决不应更新modelbinder根据发布数据创建的实体。始终从数据库中提取新的实体,并将发布的数据映射到该实体上。