从 LINQ 查询的一部分中获取值并将其添加到结果中
Posted
技术标签:
【中文标题】从 LINQ 查询的一部分中获取值并将其添加到结果中【英文标题】:Take value from part of a LINQ query and add it to the result 【发布时间】:2019-12-18 04:38:58 【问题描述】:我正在比较LayerModel
中的两个ObservableCollections
,称为SourceDrawingLayers
和TargetDrawingLayers
。
LayerModel
具有如下属性:
public string Path get; set;
public string Name get; set;
//etc
程序要求用户选择我称之为TargetDrawings
的.dwg 文件。对于每一个,我都会从该文件中捕获图层以及这些图层的属性。图中的每一层都返回一个LayerModel
,LayerModel
上的属性,例如Path
Name
Color
等,都是通过查看我正在阅读的实际绘图文件来填充的。所有LayerModel
s 都添加到TargetDrawingLayers
。
所以TargetDrawingLayers
将包含一大堆LayerModel
s,我使用Path
属性来了解给定图层存在于哪个实际绘图文件中。
SourceDrawingLayers
是通过读取单个绘图文件、读取其中的所有图层并将它们添加到集合中来填充的。
我的期望是每个TargetDrawing
都将包含与SourceDrawing
具有相同设置的相同层,因此我首先将SourceDrawingLayers
中的LayerModel
的名称与@987654345 中的LayerModel
匹配来实现这一点@。
然而,应用程序的一个要求是,我需要在 SourceDrawingLayers
中识别出任何 Name
属性在 TargetDrawingLayers
中找不到的 Name
。
我通过以下查询完成此操作:
var missingLayerQuery = SourceDrawingLayers.Where(p => !TargetDrawingLayers.Any(p2 => p2.Name == p.Name));
ObservableCollection<LayerModel> q = new ObservableCollection<LayerModel>(missingLayerQuery);
结果绑定到DataGrid
,我需要在其上显示我的查询完成的缺失层的名称,但是因为查询结果是来自源的LayerModels
的集合,我的路径列只是显示源绘图的路径,所以我的结果将如下所示:
Drawing Path Layer Name
Awesome_Source_Drawing.dwg MissingLayerName1
Awesome_Source_Drawing.dwg MissingLayerName2
Awesome_Source_Drawing.dwg MissingLayerName3
这最终不是那么有用,因为用户不知道实际上缺少什么绘图需要存在的图层。我想要的结果是这样的:
Drawing Path Layer Name
Test_Drawing_1.dwg MissingLayerName1
Test_Drawing_2.dwg MissingLayerName2
Test_Drawing_3.dwg MissingLayerName3
我的想法是向我的LayerModel
添加一个名为public string MissingLayer get; set;
的属性,然后通过查看特定的TargetDrawingLayers
LayerModel
并以这种方式设置值,找到一种从LINQ 查询中填充它的方法。
但这就是我被卡住的地方,因为我对 LINQ 还不够熟悉,无法完成它。我也不确定是否有更好/更简单的方法来解决它。所以我的问题是,我怎样才能使用这个 LINQ 查询来实现我想要的结果,如果我不能,有什么好方法呢?
谢谢。
【问题讨论】:
有一个叫except
的linq api。请看这个帖子。***.com/questions/11957685/…
谢谢 Jagadeesh 我也会检查这些答案。
Test_Drawing_1.dwg
来自哪里?你能举一个SourceDrawingLayers
和TargetDrawingLayers
的例子吗?
如果不想显示源绘图的路径,你想显示什么路径呢?它来自哪里?
@fenixil,我会用更多信息更新我的问题。谢谢。
【参考方案1】:
如果你只需要名字,你应该只选择名字;
SourceDrawingLayers.Where( ... ).Select(p => p.Name);
您可能还希望创建层名称的HashSet<string>
以有效处理数千个层。
【讨论】:
谢谢杰里米。你能帮我解决下半场吗?由于这会更改查询以返回字符串,我该如何填充 ObservableCollection?var missingLayerQuery = SourceDrawingLayers.Where(p => !TargetDrawingLayers.Any(p2 => p2.Name == p.Name)).Select(p => p.Name);
我在我的 LayerModel 上覆盖 GetHashCode。基本上我有if(This == null) return 0
,然后对于每个属性,我有一个像int PathHashCode = Path == null ? 0 : Path.GetHashCode();
这样的行,最后是return PathHashCode ^
对于每个属性。看起来对吗?
如果你只需要名字来自missingLayerQuery的LayerModels,你可以做SourceDrawingLayers.Where(x=> missingLayerQuery.Contains(x.Name));很难按照您的要求进行操作。以上是关于从 LINQ 查询的一部分中获取值并将其添加到结果中的主要内容,如果未能解决你的问题,请参考以下文章