简体   繁体   中英

Linq Query Help Needed

Say I have the following LINQ queries:

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 and targetWorkflowList have the exact same column definitions. But they both contain more columns of data than what is shown in the queries above. Those are just the columns needed for this particular issue.

difference contains all rows in sourceWorkflowList that are not contained in targetWorkflowList

Now what I would like to do is to remove all rows from sourceWorkflowList that do not exist in difference . Could someone show me a query that would do this?

Thanks very much - Randy

What you actually want is what's in the source and not in (what's in the source and not in target): 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;

And in a different form (but this will only give you the 4 columns):

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

Assuming you're using a List<T> :

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

Apologies for formatting...

If you have a constraint that requires you to only make the change in the original container do a Remove as suggested by @rob-fonseca-ensor,

If the difference list is large consider converting it to a HashSet() to get fast lookups first.

Otherwise...

If you can change the way you are getting difference use the join/intersect option suggested by @brickner as this prevents multiple iterations of the list.

If a new collection is acceptable but you already have difference (cannot replace the code that generates it):

var changedSource = source.Except(difference);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM