LinqToSQL удаляет определенные дочерние узлы из списка родительских узлов - PullRequest
0 голосов
/ 21 октября 2019

У меня есть ObservableCollection рецептов, и у каждого рецепта есть ObservableCollection ингредиентов. Допустим, я хочу изменить или удалить определенный ингредиент из всех рецептов (например, удалить арахис из всех рецептов), используя Linq. Я попытался сделать что-то вроде этого:

foreach(Recipe r in myObservableRecipes) 
{
    r.ObservableIngredients.RemoveAll(i => i.Type == PEANUTS);
}

Это не сработает, потому что список ингредиентов - это ObservableCollection, а RemoveAll - это List<T> метод. Если я добавлю ToList().RemoveAll(), он фактически не удалит их из коллекции, но удалит их из копии коллекции. Я не могу найти комбинацию Remove Where, которая, кажется, работает, поскольку Where возвращает IEnumerable, у которого нет вызова Remove.

Что я делаю:

foreach(Recipe r in myObservableRecipes)
{
    var ingToRemove = new HashSet<Ingredient>(r.myObservableIngredients.Where(i => i.Type == PEANUTS));
    foreach (Ingredient i in r.myObservableIngredients.ToList())
    {
        if(ingToRemove.Contains(i)) r.myObservableIngredients.Remove(i);
    }
    RaisePropertyChangedEvent("myObservableIngredients");
}

Это работает, но кажется неуклюжим, где пересечение наборов сущностей и наблюдаемых коллекций. На самом деле я также удаляю ту же сущность из набора сущностей (DeleteOnSubmit) в том же цикле, а затем вызываю команду отправки изменений. Это намерение разработки для использования LinqToSQL сущностей с WPF и парадигмой ObservableCollections/CollectionViewSource?

1 Ответ

0 голосов
/ 22 октября 2019

Смысл использования ObservableCollection<T> в том, что вы можете добавлять или удалять элементы из него и обновлять пользовательский интерфейс без создания дополнительных коллекций.

Просто используйте вложенный простой старый цикл for:

for (int i = myObservableRecipes.Count - 1; i >= 0; --i)
{
    Recipe r = myObservableRecipes[i];
    for (int j = r.myObservableIngredients.Count - 1; j >= 0; j--)
    {
        Ingredient ing = r.myObservableIngredients[j];
        if (ing.Type == PEANUTS)
            r.myObservableIngredients.RemoveAt(j);
    }
    //remove recipes without any remaining ingredients
    if (r.myObservableIngredients.Count == 0)
        myObservableRecipes.RemoveAt(i);
}

Это не "неуклюжий" по сравнению с многократным повторением одной и той же коллекции с использованием LINQ и созданием дополнительных коллекций.

...