C# 如何比较linq中两个列表中的子项的属性

C# 如何比较linq中两个列表中的子项的属性,c#,linq,C#,Linq,我有以下目标: public interface ITray { int OrderNo {get; set;} IEnumerable<ITrayItem> TrayItems {get;} } public interface ITrayItem { int Aisle {get; set;} } 公共接口ITray { int OrderNo{get;set;} IEnumerable TrayItems{get;} } 公共接口ITrayItem { int通道{get;

我有以下目标:

public interface ITray
{
int OrderNo {get; set;}
IEnumerable<ITrayItem> TrayItems {get;}
}

public interface ITrayItem
{
int Aisle {get; set;}
}
公共接口ITray
{
int OrderNo{get;set;}
IEnumerable TrayItems{get;}
}
公共接口ITrayItem
{
int通道{get;set;}
}
现在,我有两个列表对象

List<ITray> selectedTrays
List<ITray> poolTrays
列出所选光线
列出游泳池托盘
我要做的是针对poolTrays中的每个元素,比较所选托盘列表中的通道。如果所有通道的匹配,我想将其添加到要返回的托盘列表中。 我只是想让linq处理查询列表中集合的属性并返回列表中匹配的项

这就是我目前的情况:

List<int> selectedAisles = (from tray in selectedTrays
                            from item in tray.TrayItems
                            select item.Aisle).Distinct().ToList()

List<ITray> trayswithMatchingAisles =
           (from t in poolTrays
            from item in t.TrayItems
            where selectedAisles.Contains(item.Aisle)
            select t).ToList();
List selectedailes=(从selectedTrays中的托盘)
从tray.TrayItems中的项目
选择item.roadway).Distinct().ToList()
列出带有匹配岛的Tray=
(从池中的t开始)
从t.TrayItems中的项目
所选位置岛。包含(项目。过道)
选择t.ToList();
因此,如果我选择了托架A、B、C,托架中有通道 A[1,2,3]B[4,5,6]c[7,8,9]

然后,通道[7,9]中带有TrayItems的池托盘应成功返回,但列表中不应返回带有TrayItems[7,8,9,10]的池托盘


目前,我正在我的poolTray列表中传入(仅)[7,9],在我的Linq查询中返回了它的两个实例

var result = poolTrays.Where(x => selectedTrays.Any(z=>z.TrayItems.Select(y => y.Aisle)
                                                            .Intersect(x.TrayItems.Select(k => k.Aisle))
                                                            .Count() == x.TrayItems.Count()));
List<int> selectedAisles = 
    (from tray in selectedTrays
     from item in tray.TrayItems
     select item.Aisle)
    .Distinct().ToList();

List<ITray> trayswithMatchingAisles =
    (from t in poolTrays
     where t.TrayItems.Select(i => i.Aisle)
            .All(a => selectedAisles.Contains(a))
     select t)
    .ToList();
列出所选岛屿=
(从所选光线中的托盘)
从tray.TrayItems中的项目
选择项目(通道)
.Distinct().ToList();
列出带有匹配岛的Tray=
(从池中的t开始)
其中t.TrayItems.Select(i=>i.roach)
.All(a=>selectedailes.Contains(a))
选择t)
.ToList();
但这可以简化为:

List<ITray> trayswithMatchingAisles =
    (from t in poolTrays
     where t.TrayItems.Select(i => i.Aisle)
            .All(a => selectedTrays
                .SelectMany(s => s.TrayItems)
                .Select(i => i.Aisle)
                .Contains(a))
     select t)
    .ToList();
列出带有匹配岛的Tray=
(从池中的t开始)
其中t.TrayItems.Select(i=>i.roach)
.All(a=>selectedTrays
.SelectMany(s=>s.TrayItems)
.选择(i=>i.通道)
.载有(a))
选择t)
.ToList();
或者这个:

List<ITray> trayswithMatchingAisles = poolTrays
    .Where(t => t.TrayItems
        .Select(i => i.Aisle)
        .All(a => selectedTrays
                .SelectMany(s => s.TrayItems)
                .Select(i => i.Aisle)
                .Contains(a)))
    .ToList();
List trayswithmatchingailes=poolTrays
.其中(t=>t.TrayItems
.选择(i=>i.通道)
.All(a=>selectedTrays
.SelectMany(s=>s.TrayItems)
.选择(i=>i.通道)
.包含(a)))
.ToList();

我认为您需要使用“SelectMany”扩展名,这是为了简化返回列表列表的查询

例如:

var distinctSelectedItems = selectedTrays.SelectMany(t => t.TrayItems).Select(ti => ti.Aisle).Distinct();
bool success = poolTrays.SelectMany(t => t.TrayItems).All(ti => distinctSelectedItems.Contains(ti.Aisle));
您还可以创建一个HashSet,以获得O(1)性能,而不是List.Contains的O(n)

var distinctSelectedItems = new HashSet<int>(selectedTrays.SelectMany(t => t.TrayItems).Select(ti => ti.Aisle));
bool success = poolTrays.SelectMany(t => t.TrayItems).All(ti => distinctSelectedItems.Contains(ti.Aisle));
var distinctSelectedItems=newhashset(selectedTrays.SelectMany(t=>t.TrayItems.Select(ti=>ti.roadle));
bool success=poolTrays.SelectMany(t=>t.TrayItems).All(ti=>distinctSelectedItems.Contains(ti.roach));

祝你好运。

对不起,刚刚意识到a不是c。@jazza1000你能测试一下我的答案吗?它有用吗?(刚刚编辑)。+1是的,这是一个很好的方法。如果OP对
ITrayItem
的实现覆盖了
Equals
方法,您的原始版本就可以工作了。是的,对不起,KK,这个版本工作得很好,以前的版本无法为我编译。@jazza1000以前的版本是在没有intellisense帮助的情况下手动键入的,我不得不说我还在练习
LINQ
:)