NibblyPig
NibblyPig

Reputation: 52922

Linq to SQL lambda join

Having trouble with this, I've tried following several examples but I am just not getting it. It makes perfect sense using the non-lambda way, but how do I do a join using lambda expressions?

var myCats = GetAllCats();
var myHouses = GetAllHouses();

// pseudosql:  select * from a inner join b on a.id = b.id

I have tried this:

var fullData = myCats.Join(myHouses, a => a.id, b => b.id, (a, b) => a);

which I kind of got through looking at other examples on SO, but fullData is type IEnumerable<Cat> so I can't pull any properties from Houses off it.

Upvotes: 8

Views: 40040

Answers (4)

Femaref
Femaref

Reputation: 61427

var fullData = myCats.Join(
                 myHouses, 
                 cat => cat.id, 
                 house => house.id, 
                 (cat, house) => 
                   new 
                   { 
                     Cat = cat, 
                     House = house 
                   });

Access via fullData.First().Cat... or fullData.First().House....

Upvotes: 30

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174279

The problem is, that the result of your join - the last parameter of the Join method - is a Cat, that's why fullData is of type IEnumerable<Cat>. If you want to access both, return an anonymous type:

var fullData = myCats.Join(myHouses, a => a.id, 
                                     b => b.id,
                                     (a, b) => new { Cat = a, House = b});

Upvotes: 6

Jon Hanna
Jon Hanna

Reputation: 113222

You need to define just what it is you want to select from them.

You can change your latter to:

var fullData = myCats.Join(myHouses, cat => cat.id, house => house.id, (cat, house) => new {cat, house})

which will make fullData an IQueryable of an anonymous type that looks like:

class anonymous
{
  Cat cat,
  House house
}

The equivalent in LINQy format is:

from cat in myCats join house in myHouses
  on cat.id equals house.id
  select new {cat, house}

You can also specify just what you want to select, to avoid waste:

from cat in myCats join house in myHouses
  on cat.id equals house.id
  select new {cat.id, cat.name, house.address}

Upvotes: 5

Rup
Rup

Reputation: 34408

That's because the final argument (a, b) => a means map the return result to the cats only, i.e. it's (cat, house) => cat

You can return a temporary object with the pair e.g.

(cat, house) => new { cat, house }

Upvotes: 5

Related Questions