I have two List<FileInfo> lists, SourceFiles and DestFiles. I want to build a LINQ query that will return a list of the items whose filenames are in Source but not in Dest, i.e. a left join.
My data set for SourceFiles is:
folder1\a.txt
folder1\b.txt
folder1\c.txt
folder1\d.txt
DestFiles is:
folder2\a.txt
folder2\b.txt
folder2\c.txt
so the query should return folder1\d.txt.
Following the MSDN example, I’ve tried using LINQ syntax:
var queryX = from s in SourceFiles
join d in DestFiles
on s.Name equals d.Name
into SourceJoinDest
from joinRow in SourceJoinDest.DefaultIfEmpty()
select new
{
joinRow.FullName
};
and using extension methods:
var query = SourceFiles.GroupJoin(DestFiles,
source => source.Name,
dest => dest.Name,
(source,dest) => new
{
path = source.FullName
}).Select(x => x.path.DefaultIfEmpty())
But neither one of these work; the LINQ syntax version returns Object reference not sent to an instance of an object and the extension version returns Enumeration yielded no results.
I realize that these queries are only returning sets of FullName properties and not the full FileInfo objects; I have code that takes each FullName and returns a FileInfo, and does this for each item in the query to rebuild the list. But if there’s a way to return a FileInfo directly from the query, that would be great.
I don’t think
Joinis the ideal tool here. Basically you’re looking for anExcept. The built inExceptdoesn’t have the overload to specify your properties through lambda. You will have to create your ownIEqualityComparer. You could do it, however, like this:Or, to select just the full path, you can use
Selectat the end.I would suggest having extension methods to do quick
ExceptandIntersect.Now in your case you can do just: