C# LINQ 加入对象模型集合,然后按 属性 过滤

C# LINQ Join Object Model Collections and then filter by a property

我一直在尝试编写一个 LINQ 语句来比较同一类型对象模型的两个集合中的 属性,并生成仅包含 OnOff 属性不一样。我现在只使用 LINQ 大约一个星期,所以我还在适应它。

我的理解是联接将合并两个集合并丢弃它们中完全相同的任何项目,因此您没有重复项。

我得到建议尝试 Join 来做这件事,我已经接近了,但我还没有做到。

我的模型具有 Name、OnOff、Color 等字符串属性...我试图按名称匹配集合中的模型,然后给我一个 OnOff 属性 不同的模型.

写出我需要的是,对于 SourceDrawingLayers 中的每个 LayerModel,查看 TargetDrawingLayers 中的每个 LayerModel,看看是否找到匹配 Name。如果这样做,请检查 OnOff 属性。如果它 NOT 等于,Add 它到 OnOffConflictLayers 集合。

我已经尝试使用嵌套的 foreach 语句和 from x from y LINQ 查询来执行此操作,但我得到了大量重复项。就在那时,有人向我推荐了 Join。我只是需要帮助把它带回家。

到目前为止我有这个:

            var onOffQuery = from source in SourceDrawingLayers
                         join target in TargetDrawingLayers
                         on source.Name equals target.Name
                         //give me every target where target.OnOff does not equal source.OnOff
                         select new { target.OnOff }; //I don't know if I need this line it's just where I'm stuck at right now.

完成后我必须用结果填充一个集合:

ObservableCollection<LayerModel> q = new ObservableCollection<LayerModel>(onOffQuery);
OnOffConflictLayers = q;

对于我正在尝试的这个(可能超级简单的)查询,我将不胜感激 运行。谢谢!

更新:请参阅下面我的编辑。

private void GetOnOffConflicts()
    {
        DataAccess da = new DataAccess();
        if (TargetDrawingLayers != null && TargetDrawingLayers.Count != 0)
        {
            TargetDrawingLayers.Clear();
        }
        if (OnOffConflictLayers != null && OnOffConflictLayers.Count != 0)
        {
            AllConflictLayers.Clear();
        }

        foreach (TargetDrawingModel targetDrawingModel in TargetDrawings)
        {
            foreach (var result in da.GetDrawingLayers(targetDrawingModel.DrawingPath))
            {
                TargetDrawingLayers.Add(result);
                //everything works fine up to here. My collection is populated correctly.
            }
        }

        var onOffQuery = from source in SourceDrawingLayers
                         from target in TargetDrawingLayers
                         where source.Name == target.Name && source.OnOff != target.OnOff
                         select target;

        ObservableCollection<LayerModel> q = new ObservableCollection<LayerModel>(onOffQuery);
        OnOffConflictLayers = q;
    }

编辑:下面 Matt U 的回答是正确的。我错误地没有正确设置我的目标绘图,所有 on/off 属性实际上都是相同的,所以难怪我的代码没有返回任何内容。

已将 Matt 的回答标记为正确。

听起来您正在寻找所谓的非等值连接。您将使用两个 from 子句和一个 where.

而不是 join
var onOffQuery = from source in SourceDrawingLayers
                 from target in TargetDrawingLayers
                 where source.Name == target.Name && source.OnOff != target.OnOff
                 select target;

// onOffQuery should contain the "target" objects where there is a matching Name in source, but OnOff differs.
// You can "select source" if you want the source objects

关于非等值连接和其他自定义的更多信息 "joins":https://docs.microsoft.com/en-us/dotnet/csharp/linq/perform-custom-join-operations