2010-05-21 6 views
1

Dire que j'ai les requêtes LINQ suivantes:requête LINQ Aide nécessaire

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); 

sourceWorkflowList et targetWorkflowList ont les définitions exactement les mêmes colonnes. Mais ils contiennent tous deux plus de colonnes de données que ce qui est indiqué dans les requêtes ci-dessus. Ce ne sont que les colonnes nécessaires pour ce problème particulier.

difference contient toutes les lignes de sourceWorkflowList qui ne figurent pas dans targetWorkflowList

Maintenant, ce que je voudrais faire est de supprimer toutes les lignes de sourceWorkflowList qui n'existent pas dans difference. Quelqu'un pourrait-il me montrer une requête qui ferait cela?

Merci beaucoup - Randy

+0

est l'une des valeurs dans votre requête un identifiant d'enregistrement unique? –

+0

@Matthew - Non. Mais, SubID + ReadTime + ProcessID + LineID tous ensemble comprennent une clé unique dans la table de base de données sous-jacente. –

Répondre

2

Qu'est-ce que vous voulez réellement est ce qui est dans la source et non pas (ce qui est dans la source et non dans la cible): S (S \ T) = S CUT 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; 

Et sous une forme différente (mais cela vous donnera seulement les 4 colonnes):

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

Ne serait-il pas plus simple d'utiliser Intersect? http://msdn.microsoft.com/en-us/library/system.linq.enumerable.intersect.aspx –

+0

@Rob Fonseca-Ensor: Correct. J'ai ajouté ceci à la réponse. – brickner

+0

@Brickner - Ceci est proche. Oui, je veux ce qui est dans la source qui n'est pas dans la cible, mais je veux seulement que la comparaison soit faite sur les quatre colonnes montrées dans mon message original. Il y a trois colonnes supplémentaires dans le tableau que je ne veux pas utiliser pour la comparaison. –

1

Supposons que vous utilisez un List<T>:

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

Toutes mes excuses pour le formatage ...

1

Si vous avez une contrainte qui vous oblige à faire que le changement dans le récipient d'origine faire un Supprimer comme suggéré par @ rob-fonseca-Ensor,

Si la liste des différences est grande envisager de le convertir en un HashSet() pour obtenir des recherches rapides en premier.

Sinon ...

Si vous pouvez changer la façon dont vous obtenez différence utiliser l'option join/recouper proposée par @brickner car cela empêche plusieurs itérations de la liste.

Si une nouvelle collection est acceptable, mais vous avez déjà différence (ne peut pas remplacer le code qui le génère):

var changedSource = source.Except(difference);