LinqToSQL从父节点列表中删除特定的子节点

时间:2019-10-21 20:25:42

标签: c# wpf linq-to-sql

我有ObservableCollection个食谱,每个食谱都有ObservableCollection个配料。假设我要使用Linq修改或从所有食谱中删除某些成分(例如,从所有食谱中删除花生)。我已经尝试做过这样的事情:

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

但这不起作用,因为成分列表是ObservableCollection,而RemoveAllList<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 :(得分:0)

使用ObservableCollection<T>的全部目的是,您可以在其中添加或删除项,并且可以在不创建任何其他集合的情况下更新UI。

只需使用嵌套的旧式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多次重复同一集合并创建其他集合相比,这并不“笨拙”。