web-dev-qa-db-fra.com

LINQ rejoint deux DataTables

Salut, j'ai un problème pour joindre deux DataTables à l'aide de LINQ. Les tableaux ont des colonnes comme celle-ci:

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

J'ai utilisé linq pour rejoindre comme ceci:

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<string>("ID") equals dataRows2.Field<string>("ID")

             select dtResult.LoadDataRow(new object[]
             {
                dataRows1.Field<string>("ID"),
                dataRows1.Field<string>("name"),
                dataRows2.Field<int>("stock"),
              }, false);
result.CopyToDataTable();

Le problème est que le résultat n'affiche que les ID qui figurent dans le tableau 2.

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

Je dois également montrer les éléments manquants. Voici le résultat recherché:

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

Je crois que je devrais faire la jointure externe gauche, mais je n'ai pas assez de connaissances sur linq. Aide appréciée. Merci!

21
user1080533

Cela vous laissera par défaut à 0 si la ligne n'existe pas dans le tableau 2:

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

MSDN source

27
Sven Grosen

essaye ça:

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};
4
Masoume Karvar

essaye ça

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

vous devez simplement utiliser clause join..into comme ceci

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