Ok bo już chyba posunąłem się o krok do przodu (a przynajmniej takie mam wrażenie). Otrzymuję obecnie taki błąd:
Database operation expected to affect 1 row(s) but actually affected 0 row(s). Data may have been modified or deleted since entities were loaded. See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.”
Z kolei w debugerze mam informacje, że śledzony jest nie tylko sam Meal
, ale także MealProducts
(wcześniej był tylko Meal
).
Dodam tylko, że dodałem nowy produkt podczas edycji o Id=6
, ale ma status Modified, a chyba powinien mu nadać Added, bo o takim kluczu nie ma żadnego rekordu w MealProducts
EDIT
Dla tych, którzy szukaliby rozwiązania. Poradziłem sobie z tym trochę na piechotę:
public Meal UpdateMeal(Meal updatedMeal)
{
var existingMeal = dbContext.Meals.Where(m => m.Id == updatedMeal.Id).Include(c => c.MealProducts).SingleOrDefault();
if (existingMeal != null)
{
// Update parent
dbContext.Entry(existingMeal).CurrentValues.SetValues(updatedMeal);
// Delete children
foreach (var existingMealProduct in existingMeal.MealProducts)
{
if (!updatedMeal.MealProducts.Any(c => c.MealId == existingMealProduct.MealId && c.ProductId == existingMealProduct.ProductId))
dbContext.MealProducts.Remove(existingMealProduct);
}
// Update and Insert children
foreach (var newOrUpdateMealProduct in updatedMeal.MealProducts)
{
var existingMealProduct = existingMeal.MealProducts
.Where(c => c.MealId == newOrUpdateMealProduct.MealId && c.MealId != default(int) && c.ProductId == newOrUpdateMealProduct.ProductId && c.ProductId != default(int))
.SingleOrDefault();
if (existingMealProduct != null)
// Update child
dbContext.Entry(existingMealProduct).CurrentValues.SetValues(newOrUpdateMealProduct);
else
{
// Insert child
var newMealProduct = new MealProduct
{
MealId = newOrUpdateMealProduct.MealId,
ProductId = newOrUpdateMealProduct.ProductId,
Quantity = newOrUpdateMealProduct.Quantity
};
existingMeal.MealProducts.Add(newMealProduct);
}
}
dbContext.SaveChanges();
return updatedMeal;
}
return updatedMeal;
}