Ваши (очевидно) измененные отношения не сохраняются, потому что вы действительно не меняете отношения:
context.Products.Attach(productFromForm);
Эта строка присоединяет productFromForm
AND productFromForm.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();
Это станет намного проще, если вы выставите внешние ключикак свойства в модели - как уже говорилось в ответе @ Лентности и в ответе на ваш предыдущий вопрос.Со свойствами FK (и при условии, что вы привязываете Product.CategoryID
непосредственно к представлению, а не 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();