2010-05-21 253 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);