【问题标题】:Entity framework does not save my data to sql server实体框架不会将我的数据保存到 sql server
【发布时间】:2014-10-28 11:27:52
【问题描述】:

我有下面的代码。它使用实体框架(5.0)来处理数据输入/输出到 sql server(2008)。不幸的是,修改后的数据无法成功保存到数据库。任何帮助我的人都会非常感激。


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>

【问题讨论】:

  • 您不应该将 EntityFramework 对象用作 ViewModel,但这是一个完全独立的问题。 UpdateModel 的代码在哪里?你编码 var northwind = new NorthwindEntities();北风.SaveChanges();是与您从 ProductEditViewModel 获得的产品不同的上下文。

标签: c# asp.net asp.net-mvc entity-framework linq-to-entities


【解决方案1】:

您的问题是您尝试通过与您更新的上下文不同的上下文进行更新。下面的代码就是问题所在:

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

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

将在 vm 的上下文中更新模型。行:

var northwind = new NorthwindEntities()

创建一个尚未编辑的新上下文。您可以向 ProductEditViewModel 添加保存/更新方法(不是好的结构),也可以创建上下文,获取 vm 实例,更新它,然后保存它。

【讨论】:

    【解决方案2】:

    问题是我试图通过与我更新的上下文不同的上下文进行更新。感谢 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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多