2016-12-27 118 views
0

我的主題開頭是here如何在1個視圖中實現2個模型的編輯方法

使用DropDownList不允許我編輯作者的名字..但是這個解決方案真的很好。

我需要編輯所有4個字段,如名稱,標題,年份和價格。

我儘量讓類似的複合模式:

public class BookAuthorCompositeModel 
{ 
    public Author author { get; set; } 
    public Book book { get; set; } 
} 

更改我的get方法:

// 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") 
} 

但蹊蹺的是Post方法:

[HttpPost] 
public ActionResult Edit(Book book) 
{ 
    if (ModelState.IsValid) 
    { 
     dbBooks.Entry(BAmodel.book).State = EntityState.Modified; 
     dbBooks.Entry(BAmodel.author).State = EntityState.Modified; 

     dbBooks.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 
    return View(book); 
} 

dbBooks.SaveChanges();導致錯誤(存儲更新,插入或刪除語句影響了意外的行數(0)。)。我認爲使用這種ViewModel有助於編輯所有行,但它不會將數據發送到數據庫,並且我不明白什麼是錯誤的。

+0

FWIW,您應該*從不*更新由模型綁定器創建的實體從發佈數據。始終將新實體從數據庫中拉出來,並將發佈的數據映射到其上。 –

回答

2

如果我理解正確,你想要的是更新上下文「書」和上下文「作者」在相同的API方法。

要做到這一點,首先我會做一個包含兩個對象,你已經有一個視圖模型:

public class BookAuthorCompositeModel 
{ 
    public Author author { get; set; } 
    public Book book { get; set; } 
} 

(這可以被修改爲了進行驗證,也許創造了驗證新對象至少,但我們繼續吧)

現在,您需要在API調用中接收相同的ViewModel,然後根據對象執行相應的操作。爲此,我通常會在我的上下文中執行Get調用,以獲取要修改的對象。然後我可以自由更新我的上下文:

[HttpPost] 
    public ActionResult Edit(BookAuthorCompositeModel model) 
    { 
     ... 
    } 

要獲取要修改的對象,取決於您使用的是什麼。簡單的存儲庫模式,單元模式,並不重要。當你得到Book條目時,只需修改它,使用更新函數,我相信它是dbBooks.BookContext.Update(book),其中「book」是可變的。事情是這樣的:

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

book.name = "New Name"; 

dbBooks.BooksContext.Update(book); 
dbBooks.SaveChanges(); 

用於獲取和更新(獲得()和.Update())必須從模式的,你正在使用,但也許這可以幫助你的方法。

祝你好運!

相關問題