Вот моя ситуация - у меня есть БД, в которой есть несколько таблиц с именами recipes , ингредиенты и recipes_ingredients .
Рецепты состоят из 1+ ингредиентов.
recipes_ingredients содержит FK между рецептами и ингредиентов таблицы.
Сгенерированные классы recipe
и ingredient
и recipe
имеют свойство навигации, которое выглядит так:
public virtual ICollection<ingredients> ingredients { get; set; }
Отлично, я понимаю, что я получил сгенерированный класс recipe
и сгенерированный класс ingredient
, и что таблица recipes_ingredients
1030 * не генерирует класс, поскольку EF рассматривает это просто как свойство навигации.
Теперь у меня есть функция с именем SetIngredientsForRecipe
, которая выглядит так (за исключением кода try-catch для краткости:
public void SetIngredientsForRecipe(long recipeId, List<string> ingredients)
{
using (var db = new FoodEntities(ConnectionString, null, null))
{
var existing = GetCurrentIngredients(recipeId);
var toRemove = existing.Except(ingredients);
var toAdd = ingredients.Except(existing);
var recipe = db.recipes.Where(r => r.Id == recipeId).FirstOrDefault();
foreach (var name in toRemove)
{
var entry = recipe.ingredients.Where(i => i.Name == name).FirstOrDefault();
recipe.ingredients.Remove(entry);
}
foreach (var name in toAdd)
{
var entry = db.ingredients.Where(i => i.Name == name).FirstOrDefault();
recipe.ingredients.Add(entry);
}
db.SaveChanges();
}
}
Цель, как следует из названия, состоит в том, чтобы обновить список ингредиентов для данного рецепта только до того, что находится в списке. Я все еще чувствую себя комфортно с EF и задаюсь вопросом, есть ли лучший (более эффективный?) Способ выполнить то, что я пытаюсь сделать.
** * 1040 1041 * Последующий:
Следуя предложениям ntziolis ниже, я решил использовать
recipe.ingredients.Clear()
, чтобы убрать все, что было в карте рецепта / ингредиента, а затем использовать насмешку, которая была упомянута, чтобы быстро добавить новые. Примерно так:
foreach (var name in ingredients)
{
// Mock an ingredient since we just need the FK that is referenced
// by the mapping table - the other properties don't matter since we're
// just doing the mapping not inserting anything
recipe.ingredients.Add(new Ingredient()
{
Name = name
});
}
и это работает очень хорошо.