LINQ une dos DataTables

Hola, tengo un problema para unir dos DataTables con LINQ. Las tablas tienen columnas como esta:

table1 table2 ID, name ID, stock 1, item1 1, 100 2, item2 3, 50 3, item3 

Usé linq para unirme así:

 DataTable dtResult = new DataTable(); dtResult.Columns.Add("ID", typeof(string)); dtResult.Columns.Add("name", typeof(string)); dtResult.Columns.Add("stock", typeof(int)); var result = from dataRows1 in table1.AsEnumerable() join dataRows2 in table2.AsEnumerable() on dataRows1.Field("ID") equals dataRows2.Field("ID") select dtResult.LoadDataRow(new object[] { dataRows1.Field("ID"), dataRows1.Field("name"), dataRows2.Field("stock"), }, false); result.CopyToDataTable(); 

El problema es que el resultado solo muestra las ID que están en la tabla2.

 dtResult ID, name, stock 1, item1, 100 3, item3, 50 

Necesito mostrar también los elementos faltantes. Este es el resultado deseado:

 dtResult ID, name, stock 1, item1, 100 2, item2, 0 //Prefer if it is "0", otherwise can be left "null" 3, item3, 50 

Creo que debería hacer la combinación externa izquierda, pero no tengo suficiente conocimiento sobre linq. Ayuda apreciada. ¡Gracias!

Esto te dejará predeterminado a 0 si la fila no existe en la tabla 2:

 var result = from dataRows1 in table1.AsEnumerable() join dataRows2 in table2.AsEnumerable() on dataRows1.Field("ID") equals dataRows2.Field("ID") into lj from r in lj.DefaultIfEmpty() select dtResult.LoadDataRow(new object[] { dataRows1.Field("ID"), dataRows1.Field("name"), r == null ? 0 : r.Field("stock") }, false); 

Fuente MSDN

prueba esto:

 var result = from dataRows1 in table1.AsEnumerable() join dataRows2 in table2.AsEnumerable() on dataRows1.ID equals dataRows2.ID into ps from r in ps.DefaultIfEmpty() select new { C= dataRows1 , r == null ? 0 : dataRows2.Stock}; 

simplemente necesitas usar la cláusula join..into como esta

 var result = from dataRows1 in table1.AsEnumerable() join dataRows2 in table2.AsEnumerable() on dataRows1.Field("ID") equals dataRows2.Field("ID") into rows from row in rows.DefaultIfEmpty() select dtResult.LoadDataRow(new object[] { dataRows1.Field("ID"), dataRows1.Field("name"), row==null? null : row.Field("stock"), }, false); 

prueba esto

 var result = from dataRows1 in table1.AsEnumerable() join dataRows2 in table2.AsEnumerable() on dataRows1.Field("ID") equals dataRows2.Field("ID") into lj from r in lj.DefaultIfEmpty() select dtResult.LoadDataRow(new object[] { dataRows1.Field("ID"), dataRows1.Field("name"), r == null ? 0 : dataRows2.Field("stock") }, false);