2014-09-03 103 views
0

我有下面的代碼。它使用實體框架(5.0)來處理/輸出到sql server(2008)的數據。不幸的是,修改後的數據不能成功保存到數據庫。任何身體幫助我將非常感激。實體框架不會將我的數據保存到sql server


using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

using System.Web.Mvc; 

namespace MvcApplication1.Models 
{ 
    public class ProductEditViewModel 
    { 
     NorthwindEntities northwind = new NorthwindEntities(); 

     public Product Product; 

     public ProductEditViewModel(Int32 ProductId) 
     { 
      Product = (from pro in northwind.Products 
         where pro.ProductID == ProductId 
         select pro).FirstOrDefault(); 
     } 

     // For DropDownListFor need IEnumerable<SelectListItem> 
     public IEnumerable<SelectListItem> SupplierItems 
     { 
      get 
      { 
       var q = from sup in northwind.Suppliers.AsEnumerable() 
         select new SelectListItem 
          { 
           Text = sup.CompanyName, 
           Value = sup.SupplierID.ToString(), 
           Selected = sup.SupplierID == Product.SupplierID 
          }; 

       return q; 
      } 
     } 

     // For RadioButtonFor need below 
     public IEnumerable<Category> CategorieItems 
     { 
      get 
      { 
       var q = from cat in northwind.Categories.AsEnumerable() select cat; 
       return q; 
      } 
     } 
    } 
} 

[HttpGet] 
public ActionResult ProductEdit(Int32 ProductId) 
{ 
    var vm = new ProductEditViewModel(ProductId); 
    return View(vm); 
} 

[HttpPost] 
public ActionResult ProductEdit(Int32 ProductId, FormCollection fc) 
{ 
    var vm = new ProductEditViewModel(ProductId); 
    UpdateModel(vm.Product, "Product"); 

    var northwind = new NorthwindEntities(); 
    northwind.SaveChanges(); 

    return View(vm); 
} 

@model MvcApplication1.Models.ProductEditViewModel 

@{ 
    Layout = null; 
} 

<script type="text/javascript"> 

</script> 

<!DOCTYPE html> 

<html> 
<head> 
    <meta name="viewport" content="width=device-width" /> 
    <title>ProductEdit</title> 
</head> 
<body> 
    <script src="~/Scripts/jquery-1.10.2.min.js"></script> 
    <script src="~/Scripts/jquery.validate.min.js"></script> 
    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> 


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

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

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

      <div class="form-group"> 
       @Html.LabelFor(model => model.Product.SupplierID, "SupplierID", htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @*DropDownList is for deiplay purpose*@ 
        @*@Html.DropDownList("SupplierID", Model.SupplierItems, htmlAttributes: new { @class = "form-control" })*@ 

        @*DropDownListFor is for Edit purpose*@ 
        @Html.DropDownListFor(model => model.Product.SupplierID, Model.SupplierItems, htmlAttributes: new { @class = "form-control" }) 
       </div> 
      </div> 

      <div class="form-group"> 
       @Html.LabelFor(model => model.Product.CategoryID, "CategoryID", htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @*RadioButton is for Display purpose*@ 
        @*@foreach (var Categorie in Model.CategorieItems) 
         { 
          @Html.RadioButton("CategoryID", Categorie.CategoryID, Model.CategorySelectedId == Categorie.CategoryID) @Categorie.CategoryName; @:&nbsp;&nbsp;&nbsp; 
         }*@ 

        @*RadioButtonFor is for Edit purpose*@ 
        @foreach (var Categorie in Model.CategorieItems) 
        { 
         @Html.RadioButtonFor(model => model.Product.CategoryID, Categorie.CategoryID) @Categorie.CategoryName; @:&nbsp;&nbsp;&nbsp; 
        } 

       </div> 
      </div> 

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

      <div class="form-group"> 
       @Html.LabelFor(model => model.Product.Discontinued, htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        <div class="checkbox"> 
         @Html.EditorFor(model => model.Product.Discontinued) 
         @Html.ValidationMessageFor(model => model.Product.Discontinued, "", new { @class = "text-danger" }) 
        </div> 
       </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> 
</body> 
</html> 

+3

一個你不應該用你的EntityFramework OBJE cts作爲你的ViewModel,但這是一個完全獨立的問題。您的代碼UpdateModel在哪裏?你的代碼var northwind = new NorthwindEntities(); northwind.SaveChanges();與您從ProductEditViewModel獲得的產品不同的上下文。 – 2014-09-03 20:42:35

回答

0

問題是我正在嘗試通過與我更新的不同上下文進行更新。感謝BBlake先生找到問題。正確的代碼都低於:


using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace MvcApplication1.Models 
{ 
    public class Repository 
    { 
     public NorthwindEntities northwind; 

     public Repository() 
     { 
      northwind = new NorthwindEntities(); 
     } 

     public Product GetProductById(Int32 ProductId) 
     { 
      return (from pro in northwind.Products 
        where pro.ProductID == ProductId 
        select pro).FirstOrDefault(); 
     } 

     public void Save() 
     { 
      this.northwind.SaveChanges(); 
     } 
    } 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

using System.Web.Mvc; 

namespace MvcApplication1.Models 
{ 
    public class ProductEditViewModel 
    { 
     public Repository repository = new Repository(); 

     public Product Product; 

     public ProductEditViewModel() 
     { 
      ; 
     } 

     // For DropDownListFor need IEnumerable<SelectListItem> 
     public IEnumerable<SelectListItem> SupplierItems 
     { 
      get 
      { 
       var q = from sup in repository.northwind.Suppliers.AsEnumerable() 
         select new SelectListItem 
          { 
           Text = sup.CompanyName, 
           Value = sup.SupplierID.ToString(), 
           Selected = sup.SupplierID == Product.SupplierID 
          }; 

       return q; 
      } 
     } 

     // For RadioButtonFor need below 
     public IEnumerable<Category> CategorieItems 
     { 
      get 
      { 
       var q = from cat in repository.northwind.Categories.AsEnumerable() select cat; 
       return q; 
      } 
     } 
    } 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Mvc; 

using System.Web.Script.Serialization; 
using MvcApplication1.Models; 
using System.Data.Objects.SqlClient; 
using System.Data; 

namespace MvcApplication1.Controllers 
{ 
    public class HomeController : Controller 
    { 
     ProductEditViewModel vm = new ProductEditViewModel(); 

     // sample for populate sql server database table via entity framework 
     // 1. Install EntityFramework 5.0, if previous sample for using populate oracle database table via entity framework has been installed, this can be skiped : execute command at Package Manager Console "Install-Package EntityFramework -Version 5.0.0" (Oracle data access provider ODAC 12.1.0.1.2 current is not support (work with) EntityFramework version 6). If you want uninstall EntityFramework 5, using command "unInstall-Package EntityFramework -Version 5.0.0" 
     // 2. Models => Add => New item => Data => Ado.Net Entity Data Model (using EntityFramework 5.0) 
     public ActionResult ProductList() 
     { 
      var northwind = new NorthwindEntities(); // 3. this is connectionStrings name="NorthwindEntities" 

      var q = from pro in northwind.Products 
        select new ProductListViewModel 
        { 
         ProductId = pro.ProductID, 
         ProductName = pro.ProductName, 
         Supplier = pro.Supplier.CompanyName, 
         Categorie = pro.Category.CategoryName, 
         Discontinued = pro.Discontinued, 
         UnitPrice = pro.UnitPrice 
        }; 

      return View(q.ToList()); 
     } 

     [HttpGet] 
     public ActionResult ProductEdit(Int32 ProductId) 
     { 
      vm.Product = vm.repository.GetProductById(ProductId); 
      return View(vm); 
     } 

     [HttpPost] 
     public ActionResult ProductEdit(Int32 ProductId, FormCollection fc) 
     { 
      vm.Product = vm.repository.GetProductById(ProductId); 
      UpdateModel(vm.Product, "Product"); 
      vm.repository.Save(); 
      return RedirectToAction("ProductList"); 
     } 
    } 
} 

@model MvcApplication1.Models.ProductEditViewModel 

@{ 
    Layout = null; 
} 

<script type="text/javascript"> 

</script> 

<!DOCTYPE html> 

<html> 
<head> 
    <meta name="viewport" content="width=device-width" /> 
    <title>ProductEdit</title> 
</head> 
<body> 
    <script src="~/Scripts/jquery-1.10.2.min.js"></script> 
    <script src="~/Scripts/jquery.validate.min.js"></script> 
    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> 


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

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

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

      <div class="form-group"> 
       @Html.LabelFor(model => model.Product.SupplierID, "SupplierID", htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @*DropDownList is for deiplay purpose*@ 
        @*@Html.DropDownList("SupplierID", Model.SupplierItems, htmlAttributes: new { @class = "form-control" })*@ 

        @*DropDownListFor is for Edit purpose*@ 
        @Html.DropDownListFor(model => model.Product.SupplierID, Model.SupplierItems, htmlAttributes: new { @class = "form-control" }) 
       </div> 
      </div> 

      <div class="form-group"> 
       @Html.LabelFor(model => model.Product.CategoryID, "CategoryID", htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        @*RadioButton is for Display purpose*@ 
        @*@foreach (var Categorie in Model.CategorieItems) 
         { 
          @Html.RadioButton("CategoryID", Categorie.CategoryID, Model.CategorySelectedId == Categorie.CategoryID) @Categorie.CategoryName; @:&nbsp;&nbsp;&nbsp; 
         }*@ 

        @*RadioButtonFor is for Edit purpose*@ 
        @foreach (var Categorie in Model.CategorieItems) 
        { 
         @Html.RadioButtonFor(model => model.Product.CategoryID, Categorie.CategoryID) @Categorie.CategoryName; @:&nbsp;&nbsp;&nbsp; 
        } 

       </div> 
      </div> 

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

      <div class="form-group"> 
       @Html.LabelFor(model => model.Product.Discontinued, htmlAttributes: new { @class = "control-label col-md-2" }) 
       <div class="col-md-10"> 
        <div class="checkbox"> 
         @Html.EditorFor(model => model.Product.Discontinued) 
         @Html.ValidationMessageFor(model => model.Product.Discontinued, "", new { @class = "text-danger" }) 
        </div> 
       </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> 
</body> 
</html> 

0

您的問題是,你正在嘗試通過不同的環境比你更新了一個更新。以下代碼是問題:

var vm = new ProductEditViewModel(ProductId); 
UpdateModel(vm.Product, "Product"); 

var northwind = new NorthwindEntities(); 
northwind.SaveChanges(); 

將更新vm上下文中的模型。該行:

var northwind = new NorthwindEntities() 

創建一個尚未編輯的新上下文。您可以將保存/更新方法添加到ProductEditViewModel(不是很好的結構),也可以創建上下文,獲取vm的實例,更新它,然後保存它。

相關問題