![](/img/trans.png)
[英]ASP.NET MVC Entity Framework 6 Navigation Property not saving on SaveChanges() Repository Pattern on Edit
[英]Can't SaveChanges with Entity Framework in ASP.Net MVC 3 project
学习asp.net mvc 3 + EF代码优先。 我是两个新手。 我的例子是微不足道的,但我仍然无法使其发挥作用。 缺少一些简单而明显的东西......
我上课了:
public class Product
{
[HiddenInput(DisplayValue = false)]
public int ProductID { get; set; }
[Required(ErrorMessage = "Please enter a product name")]
public string Name { get; set; }
[Required(ErrorMessage = "Please enter a description")]
[DataType(DataType.MultilineText)]
public string Description { get; set; }
[Required]
[Range(0.01, double.MaxValue, ErrorMessage = "Please enter a positive price")]
public decimal Price { get; set; }
[Required(ErrorMessage = "Please specify a category")]
public string Category { get; set; }
}
和DbContext
:
public class EFDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
和一个存储库:
public class EFProductRepository : IProductRepository
{
private EFDbContext context = new EFDbContext();
public IQueryable<Product> Products
{
get
{
return context.Products;
}
}
public void SaveProduct(Product product)
{
if (product.ProductID == 0)
context.Products.Add(product);
context.SaveChanges();
}
}
mvc控制器:
public class AdminController : Controller
{
private IProductRepository repository;
public AdminController(IProductRepository repo)
{
repository = repo;
}
public ViewResult Index()
{
return View(repository.Products);
}
public ViewResult Edit(int productId)
{
Product product = repository.Products.FirstOrDefault(p => p.ProductID == productId);
return View(product);
}
[HttpPost]
public ActionResult Edit(Product product)
{
if (ModelState.IsValid)
{
repository.SaveProduct(product);
TempData["message"] = string.Format("{0} has been saved", product.Name);
return RedirectToAction("Index");
}
else
{
// there is something wrong with the data values
return View(product);
}
}
}
它让我看到产品列表,打开编辑视图,根据属性集验证所有内容......
当我保存经过验证的更改时,它将转到Http Post Edit
方法并进行必要的SaveChanges()
。
它没有抛出任何异常,它继续并将我重定向到产品列表。
编辑的项目保持不变。
底层数据库(通过web.config
connectionstrings
web.config
connectionstrings
)也保持不变。
您需要附加在EF外部创建的实体实例,并让EF知道它已被修改。
public void SaveProduct(Product product)
{
if (product.ProductID == 0)
{
context.Products.Add(product);
}
else
{
context.Products.Attach(product);
context.Entry(product).State = EntityState.Modified;
}
context.SaveChanges();
}
您应该在SaveChanges
之前Attach
Product
实例Attach
到上下文
public void SaveProduct(Product product)
{
if (product.ProductID == 0)
context.Products.Add(product);
else
{
context.Products.Attach(product);
context.Entry(product).State = EntityState.Modified;
}
context.SaveChanges();
}
的确,你应该附上。
假设您调用编辑(1)。 您的控制器将从您的数据库加载ID = 1的产品,并根据其属性(您在视图中声明的那些)生成HTML视图。 一旦您离开Edit(int productId)方法并且您的浏览器中显示您的视图,您的DbContext就会丢失带有该ID的产品; 它已超出范围。 如果您随后对产品进行了更改并提交了表单,ASP MVC将根据您的表单字段(以及其他内容)拼凑一个新的Product对象,并将该对象传递给Edit(产品产品)方法。 由于这是一个全新的Product对象,而旧的Product对象无论如何都超出了范围,你DbContext不知道新产品如何与你的数据库相关:它是一个新对象,它是一个现有对象,如果它存在它做它有什么变化吗? 如果附加Product对象并将其状态设置为modified,则DbContext可以开始检查哪些属性已更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.