我有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以及如何实现预期的连接。
?
来管理由第一个left join,null
值dataRows3
表添加第二个left join,以获取null
值,以获取dataRows2
和dataRows1
表中现有的数据。 注意,最后一个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();
希望您能找到帮助。
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()我提供的代码可为您带来预期的结果。但也许您需要再添加一个“选择”以形成所需的数据结构。