Pat*_*ins 2 c# asp.net-mvc entity-framework asp.net-mvc-3 entity-framework-4.3
我用Northwind数据库做了一个小项目来说明问题所在.
这是控制器的动作:
[HttpPost]
public ActionResult Edit(Product productFromForm)
{
try
{
context.Products.Attach(productFromForm);
var fromBD = context.Categories.Find(productFromForm.Category.CategoryID);
productFromForm.Category = fromBD;
context.Entry(productFromForm).State = EntityState.Modified;
context.SaveChanges();
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
context在Controller的构造函数中实例化new DatabaseContext().
public class DatabaseContext:DbContext
{
public DatabaseContext()
: base("ApplicationServices") {
base.Configuration.ProxyCreationEnabled = false;
base.Configuration.LazyLoadingEnabled = false;
}
public DbSet<Product> Products { get; set; }
public DbSet<Category> Categories { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder){
modelBuilder.Configurations.Add(new ProductConfiguration());
modelBuilder.Configurations.Add(new CategoriesConfiguration());
}
private class ProductConfiguration : EntityTypeConfiguration<Product> {
public ProductConfiguration() {
ToTable("Products");
HasKey(p => p.ProductID);
HasOptional(p => p.Category).WithMany(x=>x.Products).Map(c => c.MapKey("CategoryID"));
Property(p => p.UnitPrice).HasColumnType("Money");
}
}
private class CategoriesConfiguration : EntityTypeConfiguration<Category> {
public CategoriesConfiguration() {
ToTable("Categories");
HasKey(p => p.CategoryID);
}
}
}
public class Category {
public int CategoryID { get; set; }
public string CategoryName { get; set; }
public string Description { get; set; }
public virtual ICollection<Product> Products { get; set; }
}
public class Product {
public int ProductID { get; set; }
public string ProductName { get; set; }
public string QuantityPerUnit { get; set; }
public decimal UnitPrice { get; set; }
public Int16 UnitsInStock { get; set; }
public Int16 UnitsOnOrder { get; set; }
public Int16 ReorderLevel { get; set; }
public bool Discontinued { get; set; }
public virtual Category Category { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
问题是我可以保存产品中的任何内容,但不能保存类别的更改.
对象productFromForm在productFromForm.Product.ProductID中包含新的CategoryID而没有问题.但是,当我Find()从上下文中检索对象的类别时,我有一个没有Name和Description的对象(都保持为NULL)并且SaveChanges()即使ID已经为属性更改,也不会修改引用Category.
知道为什么吗?
您(显然)改变的关系不会得到保存,因为您没有真正改变关系:
context.Products.Attach(productFromForm);
Run Code Online (Sandbox Code Playgroud)
该行将productFromFormAND 附加productFromForm.Category到上下文中.
var fromBD = context.Categories.Find(productFromForm.Category.CategoryID);
Run Code Online (Sandbox Code Playgroud)
该行返回附加的对象productFromForm.Category,而不是数据库中的对象.
productFromForm.Category = fromBD;
Run Code Online (Sandbox Code Playgroud)
该行分配相同的对象,因此它什么都不做.
context.Entry(productFromForm).State = EntityState.Modified;
Run Code Online (Sandbox Code Playgroud)
此行仅影响标量属性productFromForm,而不影响任何导航属性.
更好的方法是:
// Get original product from DB including category
var fromBD = context.Products
.Include(p => p.Category) // necessary because you don't have a FK property
.Single(p => p.ProductId == productFromForm.ProductId);
// Update scalar properties of product
context.Entry(fromBD).CurrentValues.SetValues(productFromForm);
// Update the Category reference if the CategoryID has been changed in the from
if (productFromForm.Category.CategoryID != fromBD.Category.CategoryID)
{
context.Categories.Attach(productFromForm.Category);
fromBD.Category = productFromForm.Category;
}
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
如果在模型中将外键作为属性公开,则会变得容易得多 - 正如@Laniency的答案和前一个问题的答案中所述.使用FK属性(并假设您Product.CategoryID直接绑定到视图而不是Product.Category.CategoryID),上面的代码简化为:
var fromBD = context.Products
.Single(p => p.ProductId == productFromForm.ProductId);
context.Entry(fromBD).CurrentValues.SetValues(productFromForm);
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
或者,您可以设置可以Modified使用FK属性的状态:
context.Entry(productFromForm).State = EntityState.Modified;
context.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3975 次 |
| 最近记录: |