gpt4 book ai didi

c# - Entity Framework 4.3 with MVC on Edit 不保存复杂对象

转载 作者:行者123 更新时间:2023-11-30 19:30:09 25 4
gpt4 key购买 nike

我用 Northwind 数据库做了一个小项目来说明这个问题。

这是 Controller 的 Action :

[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();
}
}

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; }
}

问题是我可以保存产品中的任何内容,但不能保存类别的更改。

对象 productFromForm 在 productFromForm.Product.ProductID 中包含新的 CategoryID 没有问题。但是,当我 Find() 从上下文中检索对象的类别时,我有一个没有名称和描述的对象(都保持为 NULL)并且 SaveChanges() 没有' 即使属性 Category 的 ID 已更改,也要修改引用。

知道为什么吗?

最佳答案

你(显然)改变的关系没有得到保存,因为你并没有真正改变关系:

context.Products.Attach(productFromForm);

此行将 productFromFormproductFromForm.Category 附加到上下文。

var fromBD = context.Categories.Find(productFromForm.Category.CategoryID);

此行返回附加对象 productFromForm.Category,而不是数据库中的对象。

productFromForm.Category = fromBD;

这一行分配了同一个对象,所以它什么都不做。

context.Entry(productFromForm).State = EntityState.Modified;

此行仅影响 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();

如果您将外键公开为模型中的属性,就会变得容易得多 - 正如@Leniency 的回答和您之前问题的回答中已经说过的那样。使用 FK 属性(并假设您将 Product.CategoryID 直接绑定(bind)到 View 而不是 Product.Category.CategoryID),上面的代码简化为:

var fromBD = context.Products
.Single(p => p.ProductId == productFromForm.ProductId);
context.Entry(fromBD).CurrentValues.SetValues(productFromForm);
context.SaveChanges();

或者,您可以将状态设置为 Modified,这将与 FK 属性一起使用:

context.Entry(productFromForm).State = EntityState.Modified;
context.SaveChanges();

关于c# - Entity Framework 4.3 with MVC on Edit 不保存复杂对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9875355/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com