具有多个数据表的外部联接

问题描述 投票:0回答:2

我有3个数据表

DataTable1

Id  Version     URL     Owner
1   1           "xx"    "alice" 
2   1           "yy"    "bob"
3   1           "zz"    "Mike"
4   1           "ww"    "Rob"
5   1           "ww"    "Bick"

DataTable2

Id  Version     DomainID    Region      Type
1   1           aa          asia        1
2   1           bb          europe      2
3   1           cc          africa      1
4   1           dd          aus1        0

DataTable3

Id  Size    FreeSpace
aa  2500    2000
bb  3300    3000
cc  5500    50

预期加入

Id  Version     URL     Owner       DomainID    Region      Type    Size    Freespace
1   1           "xx"    "alice"     aa          asia        1       2500    2000
2   1           "yy"    "bob"       bb          europe      2       3300    3000
3   1           "zz"    "Mike"      cc          africa      1       5500    50
4   1           "ww"    "sean"      dd          aus1        0       null    null    
5   1           "ww"    "Bick"      null        null        null    null    null

我正在使用Linq对这些表执行联接操作,如下所示:

// Datatable1 joins with Datatable2 on Id and version (datatable1)  -->  Id and version (datatable2) 
   // Datatable2 joins with Datatable3 on DomainId(datatable2) --> Id(datatable3)


var result = from dataRows1 in DataTable1.AsEnumerable()
                             join dataRows2 in DataTable2.AsEnumerable() on

                             new
                             {
                                 Id = dataRows1.Field<long>("Id"),
                                 Version = dataRows1.Field<long>("version")
                             } equals new
                             {
                                 Id = dataRows2.Field<long>("Id"),
                                 Version = dataRows2.Field<long>("version")
                             }
                              into tempJoin
                              from datarowc in tempJoin.DefaultIfEmpty() 
                             join dataRows3 in DataTable3.AsEnumerable() on                  
         dataRowsc.Field<long>("DomainId") equals dataRows3.Field<long>("Id")
    select new

    {
    datarow1,
    datarowc,
    datarow3
    }

我将datarowc的异常设为null。不太清楚为什么datarowc在这里为null以及如何实现预期的连接。

c# linq datatables-1.10
2个回答
0
投票
  • 您可以添加?来管理由第一个left join
  • 填充的null
  • 您还可以为dataRows3表添加第二个left join,以获取null值,以获取dataRows2dataRows1表中现有的数据。

注意,最后一个join的结果将为您提供3行而不是5行。

尝试以下查询:

var result = (//first left join
            from dataRows1 in DataTable1.AsEnumerable()
            join dataRows2 in DataTable2.AsEnumerable() on
            new
            {
                Id = dataRows1.Field<long>("Id"),
                Version = dataRows1.Field<long>("version")
            } equals 
            new
            {
                Id = dataRows2.Field<long>("Id"),
                Version = dataRows2.Field<long>("version")
            }
            into leftedResults1
            from leftedResult1 in leftedResults1.DefaultIfEmpty() 

            // second left join
            join dataRows3 in DataTable3.AsEnumerable() on                  
            leftedResult1?.Field<long>("DomainId") equals dataRows3.Field<long>("Id") into leftedResults2
            from leftedResult2 in leftedResults2.DefaultIfEmpty()
            select new
            {
              dataRows1.Id,
              dataRows1.Version,
              dataRows1.URL,
              dataRows1.Owner,
              DomainID = leftedResult1?.DomainID,
              Region = leftedResult1?.Region,
              Type = leftedResult1?.Type,
              Size = leftedResult2?.Size,
              Freespace = leftedResult2?.FreeSpace
            }).ToList();

希望您能找到帮助。


0
投票
using System.Data;
using System.Linq;

namespace CodeWars
{
    class Program
    {
        static void Main(string[] args)
        {            
            var result = datarows1.AsEnumerable()
                .Select(x => new
                    {
                        Tab1Row = x,
                        Tab2Row = datarows2.AsEnumerable().FirstOrDefault(
                            y => x.Field<int>("Id") == y.Field<int>("Id") &&
                                x.Field<int>("Version") == y.Field<int>("Version")
                        )
                    }
                )
                .Select(x => new
                    {
                        Tab1Row = x.Tab1Row,
                        Tab2Row = x.Tab2Row,
                        Tab3Row = datarows3.AsEnumerable().FirstOrDefault(
                            y => x?.Tab2Row?.Field<string>("DomainId") == y.Field<string>("Id")
                        )
                    }
                );
        }

        static DataTable datarows1 = new DataTable
        {
            Columns = {
                    { "Id", typeof(int) },
                    { "Version", typeof(int) },
                    { "URL", typeof(string) },
                    { "Owner", typeof(string) },
                },
            Rows = {
                    { 1, 1, "xx", "alice" },
                    { 2, 1, "yy", "bob" },
                    { 3, 1, "vv", "mike" },
                    { 4, 1, "ww", "rob" },
                    { 5, 1, "zz", "bick" },
                }
        };

        static DataTable datarows2 = new DataTable
        {
            Columns = {
                    { "Id", typeof(int) },
                    { "Version", typeof(int) },
                    { "DomainID", typeof(string) },
                    { "Region", typeof(string) },
                    { "Type", typeof(int) },
                },
            Rows = {
                    { 1, 1, "aa", "asia", 1 },
                    { 2, 1, "bb", "europe", 2},
                    { 3, 1, "cc", "asia", 1},
                    { 4, 1, "dd", "aus1", 0},
                }
        };

        static DataTable datarows3 = new DataTable
        {
            Columns = {
                    { "Id", typeof(string) },
                    { "Size", typeof(int) },
                    { "FreeSpace", typeof(int) },
                },
            Rows = {
                    { "aa", 2500, 2000 },
                    { "bb", 3300, 3000 },
                    { "cc",5500, 50},
                }
        };

    }
}

。Join()执行内部联接,但是您想离开外部联接,所以请不要考虑.Join()我提供的代码可为您带来预期的结果。但也许您需要再添加一个“选择”以形成所需的数据结构。

© www.soinside.com 2019 - 2024. All rights reserved.