使用 2 个数据表进行查询

本文关键字:查询 数据表 使用 | 更新日期: 2023-09-27 18:30:18

我有2个数据表:

 dt1:                       dt2:
   | id | num | value |       | id | num | name      |
   |----+-----+-------|       |----+-----+-----------|
   |  99|    1|  +    |       | 99 |    1| tiger     |
   | 100|    2|  +    |       | 100|    2| pigeon    |
   | 101|    1|  -    |       | 101|    1| crocodile |
   | 102|    1|  +    |       | 102|    1| panther   |
                              | 105|    1| whale     |

我想将其绑定到一个数据表:

| id | num | value |  name    |
|----+-----+-------+----------|
| 99 |    1|    +  |tiger     |
| 100|    2|    +  |pigeon    |
| 101|    1|    -  |crocodile |
| 102|    1|    +  |panther   |
| 105|    1|       |whale     |

之后,我将 DataRow 绑定到 dataGridView。

我尝试创建一个查询,但其中有问题,它没有返回值:

var vquery = (from dt1 in dtable1.AsEnumerable()
              from dt2 in dtable2.AsEnumerable()
              where dt1.Field<int?>(IndexesField.F_LINK_ID) == dt2.Field<int?>(IndexesField.F_LINK_ID)
              where dt1.Field<int?>(IndexesField.F_TABKEY) == dt2.Field<int?>(IndexesField.F_TABKEY)
              select new { dt1, dt2 });

我需要做什么来纠正它?

问候亚历山大。

使用 2 个数据表进行查询

在这里应该使用 DataTable.Merge,而不是使用 LINQ。
如果您的DataTable有一个主键,那么它会自动按照您想要的方式计算出来。

dtable1.PrimaryKey = new[] { dtable1.Columns["id"] };
dtable2.PrimaryKey = new[] { dtable2.Columns["id"] };
dtable1.Merge(dtable2);
如果要

使用 LINQ,则必须模拟外部联接以获取所需的值,然后将它们插入到第三个数据表中。

void Main()
{
    DataTable dTable1 = new DataTable();
    DataTable dTable2 = new DataTable();
    dTable1.Columns.Add("id", typeof(int));
    dTable1.Columns.Add("num", typeof(int));
    dTable1.Columns.Add("value", typeof(string));
    dTable2.Columns.Add("id", typeof(int));
    dTable2.Columns.Add("num", typeof(int));
    dTable2.Columns.Add("name", typeof(string));
    dTable1.Rows.Add(new object [] { 99, 1, "+"});
    dTable1.Rows.Add(new object [] { 100, 1, "+"});
    dTable1.Rows.Add(new object [] { 101, 1, "-"});
    dTable1.Rows.Add(new object [] { 102, 1, "+"});
    dTable2.Rows.Add(new object [] { 99, 1, "tiger"});
    dTable2.Rows.Add(new object [] { 100, 1, "pigeon"});
    dTable2.Rows.Add(new object [] { 101, 1, "crocodile"});
    dTable2.Rows.Add(new object [] { 102, 1, "panther"});
    dTable2.Rows.Add(new object [] { 105, 1, "whale"});
    var vQuery = (from dt1 in dTable1.AsEnumerable()
                      join dt2 in dTable2.AsEnumerable()
                      on new { Id = dt1.Field<int?>(0), Num = dt1.Field<int?>(1) } 
                    equals new { Id = dt2.Field<int?>(0), Num = dt2.Field<int?>(1) } 
                    into temp
                    from defaultDt2 in temp.DefaultIfEmpty(null)
              select new {
                      id = (dt1 ?? temp.First()).Field<int?>(0), 
                    num = (dt1 ?? temp.First()).Field<int?>(1), 
                    value = dt1 != null ? dt1.Field<string>(2) : null,
                    name = temp.First() != null ? temp.First().Field<string>(2) : null
              }).Concat(
                (from dt1 in dTable2.AsEnumerable()
                      join dt2 in dTable1.AsEnumerable()
                      on new { Id = dt1.Field<int?>(0), Num = dt1.Field<int?>(1) } 
                    equals new { Id = dt2.Field<int?>(0), Num = dt2.Field<int?>(1) } 
                                        into temp
                    from defaultDt2 in temp.ToList<DataRow>().DefaultIfEmpty(null)
              select new 
              {
                      id = (temp.FirstOrDefault() ?? dt1).Field<int?>(0), 
                    num = (temp.FirstOrDefault() ?? dt1).Field<int?>(1), 
                    value = temp.FirstOrDefault() != null ? temp.FirstOrDefault().Field<string>(2) : null,
                    name = dt1 != null ? dt1.Field<string>(2) : null
              }));
    // At this point you will have the data you're after.
}