LINQ两种不同类型的交叉点

时间:2012-04-03 18:17:09

标签: c# linq

我有两种不同的列表类型。我需要从list1中删除list2中不存在的元素,list2元素满足某些条件。

这是我尝试过的,似乎有效,但每个元素都列出了两次。

   var filteredTracks =
                    from mtrack in mTracks 
                    join ftrack in tracksFileStatus on mtrack.id equals ftrack.Id
                    where mtrack.id == ftrack.Id && ftrack.status == "ONDISK" && ftrack.content_type_id == 234
                    select mtrack;

理想情况下,我不想创建filteredTracks的新副本,是否可以修改mTracks?

2 个答案:

答案 0 :(得分:4)

如果您正在获得重复项,那是因为您的id字段在两个序列中的一个或两个中都不是唯一的。此外,您不需要说where mtrack.id == ftrack.Id,因为必须满足该条件才能使联接成功。

我可能会在这里使用循环,但是如果您在LINQ上设置了死区,则可能需要将tracksFileStatus字段分组为Id。你发布的内容很难说清楚。

就“修改mTracks到位”而言,这可能是不可能或不值得的(我假设mTracks是从IEnumerable<T>派生的某种类型)。如果您担心这种方法的效率,那么您可能需要考虑使用其他类型的数据结构,例如以Id值作为键的字典。

答案 1 :(得分:2)

因为Q主要是关于列表...
这可能是更好的明智......

var test = (from m in mTracks
            from f in fTracks
            where m.Id == f.Id && ...
            select m);

但是你应该优化,例如
你的清单是否排序?如果是,请参阅例如Best algorithm for synchronizing two IList in C# 2.0
如果它来自Db(这里不清楚),那么你需要根据你在Db中的SQL /关系和索引构建你的linq查询,然后走一条不同的路线。
如果我是你,我会进行一个查询(对于每个列表,假设它不是Db绑定的),这样轨道首先被排序(并且通常用于比较它们的任何内容),
然后并行枚举(使用枚举器),比较过程中的其他内容(如在该链接中) 这可能是最有效的方式。
if / when它来自数据库,在'source'处进行优化 - 即获取已经排序和过滤的数据尽可能多。基本上,首先构建一个SQL,或者从linq查询中检查返回的SQL(如果需要链接,请告诉我)。