2010-05-21 135 views
1

说我有以下LINQ查询:LINQ查询帮助需要

var source = from workflow in sourceWorkflowList 
      select new { SubID = workflow.SubID, 
          ReadTime = workflow.ReadTime, 
          ProcessID = workflow.ProcessID, 
          LineID = workflow.LineID }; 

var target = from workflow in targetWorkflowList 
      select new { SubID = workflow.SubID, 
          ReadTime = workflow.ReadTime, 
          ProcessID = workflow.ProcessID, 
          LineID = workflow.LineID }; 

var difference = source.Except(target); 

sourceWorkflowListtargetWorkflowList有相同的列定义。但是它们都包含比上面查询中显示的数据更多的列。这些只是这个特定问题所需的列。

difference包含未在targetWorkflowList

包含现在我想要做的是消除由sourceWorkflowList所有行中不存在differencesourceWorkflowList所有行。有人会告诉我一个可以做到这一点的查询吗?

非常感谢 - 兰迪

+0

是在查询中唯一的记录ID值的一个? – 2010-05-21 13:08:39

+0

@Matthew - 但是,SubID + ReadTime + ProcessID + LineID一起构成底层数据库表中的唯一键。 – 2010-05-21 13:09:34

回答

2

你真正想要的是什么是源,而不是在(什么是源而不是目标):S(S \ T)= S剖分T

var result = from sourceWorkflow in sourceWorkflowList 
      join targetWorflow in targetWorkflowList on 
       new {sourceWorkflow.SubID, sourceWorkflow.ReadTime, sourceWorkflow.ProcessID, sourceWorkflow.LineID} 
       equals 
       new {targetWorflow.SubID, targetWorflow.ReadTime, targetWorflow.ProcessID, targetWorflow.LineID} 
      select sourceWorkflow; 

并以不同的形式(但这只会给你4列):

var result = sourceWorkflowList.Select(workflow => new {workflow.SubID, workflow.ReadTime, workflow.ProcessID, workflow.LineID}) 
    .Intersect(sourceWorkflowList.Select(workflow => new {workflow.SubID, workflow.ReadTime, workflow.ProcessID, workflow.LineID})); 
+1

只用Intersect会不会更容易? http://msdn.microsoft.com/en-us/library/system.linq.enumerable.intersect.aspx – 2010-05-21 13:15:14

+0

@Robon Fonseca-Ensor:正确。我已经添加了这个答案。 – brickner 2010-05-21 13:17:48

+0

@Brickner - 这很接近。是的,我希望源中的内容不在目标中,但我只希望在原始文章中显示的四列上进行比较。表中有三个额外的列,我不想用于比较。 – 2010-05-21 14:00:27

1

假设您使用的是List<T>

sourceWorkflowList.RemoveAll(
    workflow => difference.Contains(
        new { 
          SubID = workflow.SubID, 
          ReadTime = workflow.ReadTime, 
          ProcessID = workflow.ProcessID, 
          LineID = workflow.LineID 
         })); 

道歉格式化...

1

如果您有需要,你只让在原来的容器的变化做一个去除由@抢劫,丰塞卡,恩索尔的建议约束,

如果差异列表很大,请考虑将其转换为HashSet()以首先进行快速查找。

否则......

如果你可以改变你越来越差异使用由@brickner建议的加入/交叉选项,因为这阻止列表的多次迭代的方式。

如果一个新的集合是可以接受的,但是你已经有差异(不能代替产生它的代码):

var changedSource = source.Except(difference);