Para extender la respuesta de sintaxis de la cadena de expresión de Clever Human:
Si desea hacer cosas (como filtrar o seleccionar) en los campos de ambas tablas que se unen, en lugar de solo en una de esas dos tablas, puede crear un nuevo objeto en la expresión lambda del parámetro final para el método Join incorporando ambas tablas, por ejemplo:
var dealerInfo = DealerContact.Join(Dealer,
dc => dc.DealerId,
d => d.DealerId,
(dc, d) => new { DealerContact = dc, Dealer = d })
.Where(dc_d => dc_d.Dealer.FirstName == "Glenn"
&& dc_d.DealerContact.City == "Chicago")
.Select(dc_d => new {
dc_d.Dealer.DealerID,
dc_d.Dealer.FirstName,
dc_d.Dealer.LastName,
dc_d.DealerContact.City,
dc_d.DealerContact.State });
La parte interesante es la expresión lambda en la línea 4 de ese ejemplo:
(dc, d) => new { DealerContact = dc, Dealer = d }
... donde construimos un nuevo objeto de tipo anónimo que tiene como propiedades los registros DealerContact y Dealer, junto con todos sus campos.
Luego podemos usar campos de esos registros a medida que filtramos y seleccionamos los resultados, como lo demuestra el resto del ejemplo, que usa dc_d
como nombre para el objeto anónimo que construimos que tiene los registros DealerContact y Dealer como sus propiedades.