C# Can';在ASP.NETMVC3项目中使用实体框架保存更改
首先学习asp.NETMVC3+EF代码。我对两者都是新手。我的例子是微不足道的,但我仍然不能使它工作。缺少一些简单而明显的东西 我有一门课:C# Can';在ASP.NETMVC3项目中使用实体框架保存更改,c#,asp.net-mvc-3,entity-framework,ef-code-first,savechanges,C#,Asp.net Mvc 3,Entity Framework,Ef Code First,Savechanges,首先学习asp.NETMVC3+EF代码。我对两者都是新手。我的例子是微不足道的,但我仍然不能使它工作。缺少一些简单而明显的东西 我有一门课: public class Product { [HiddenInput(DisplayValue = false)] public int ProductID { get; set; } [Required(ErrorMessage = "Please enter a product name")] public s
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; }
}
它让我看到产品列表,打开编辑视图,根据属性集验证所有内容
当我保存已验证的更改时,它会转到Http PostEdit
方法并进行必要的SaveChanges()
它没有抛出任何异常,它继续并将我重定向到产品列表
编辑的项目保持不变
基础数据库(通过
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();
}
您应该在
保存更改之前将产品
实例附加到上下文中
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();
}
的确,你应该附上
假设您调用Edit(1)。您的控制器将从DB加载ID=1的产品,并根据其属性(您在视图中声明的属性)生成HTML视图。
一旦您离开Edit(int productId)方法,并且您的视图显示在浏览器中,您的DbContext就丢失了具有该ID的产品;它已经超出了范围。
如果随后对产品进行更改并提交表单,ASP MVC将根据表单字段(以及其他内容)拼凑出一个新的产品对象,并将该对象传递给Edit(Product)方法。
由于这是一个全新的产品对象,而且旧产品对象已经超出了范围,因此DbContext不知道新产品与数据库的关系:它是新对象吗?它是现有对象吗?如果它存在,它是否有任何更改?
如果附加Product对象并将其状态设置为modified,则DbContext可以开始检查哪些属性已更改。试图找出我是否使用了不同的上下文…似乎是AdminController
中的存储库
具有不同的GetHashCode()
如果在两个不同的编辑方法中选中,
不知道是否可以说smthI利用了Ninject(也研究DI),ProductID的默认值不是Int32.MinValue,而不是0吗?还有,您将如何以及何时将存储库传递给AdminController构造函数?即使如此,情况并非如此,因为我只尝试编辑现有行,您为什么说它是在EF之外创建的?在edit
“Get request”方法中,我让实体像下面这样进行编辑Product=repository.Products.FirstOrDefault(p=>p.ProductID==ProductID)
。它来自EFcontext@horghMVC Model binder在调用Edit
方法时创建Product
的新实例。请记住,web是无状态的。Get
和Post
请求不会发生在同一控制器实例内。因此,在这种场景中使用Attach
必须非常常见ario?还是有更好的整体方法?@horgh正确的方法是使用ViewModels与视图交互,并将它们来回映射到控制器中的模型实例。
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();
}
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();
}