我有3个DataTable对象,其中包含我想要加入的关系数据。 第一个模式看起来像
DataTable parent = new DataTable();
parent.Columns.Add("Id1", typeof(string));
parent.Columns.Add("Id2", typeof(string));
// more metadata
其中任何一个ID可能是DBNull,但不是两者。
两个chlid表具有相同的架构。
DataTable child = new DataTable();
child.Columns.Add("Id1", typeof(string));
child.Columns.Add("Id2", typeof(string));
child.Columns.Add("BeginDate", typeof(DateTime));
child.Columns.Add("SomeData", typeof(float));
// more data
我有一个函数,它将所有三个DataTables作为输入,并且应该返回连接表。
var dataToReturn = // will be converted to a DataTable later.
from
p in parent.AsEnumerable()
join c1 in child1.AsEnumerable()
on new {
Id1 = p["Id1"],
Id2 = p["Id2"],
}
equals new {
Id1 = c1["Id1"],
Id2 = c1["Id2"],
}
join c2 in child2.AsEnumerable()
on new {
Id1 = p["Id1"],
Id2 = p["Id2"],
BeginDate = c1["BeginDate"],
}
equals new {
Id1 = p["Id1"],
Id2 = p["Id2"],
BeginDate = c1["BeginDate"],
}
select new {
Id1 = p["Id1"],
Id2 = p["Id2"],
BeginDate = c1["BeginDate"],
Child1Data = c1["SomeData"],
Child2Data = c2["SomeData"],
}
但是,即使在这些条件上有许多非空值匹配,也不会返回任何结果。
如果我正在编写SQL(使用"与#34;不同,来自Postgres以使null = null为了简洁而返回true),我会写
select
p.Id1,
p.Id2,
c1.BeginDate,
c1.SomeData as Child1Data,
c2.SomeData as Child2Data
from
Parent p
join Child1 c1
on c1.Id1 is not distinct from p.Id1
and c1.Id2 is not distinct from p.Id2
join Child2 c2
on c2.Id1 is not distinct from p.Id1
and c2.Id2 is not distinct from p.Id2
and c2.BeginDate = c1.BeginDate
请注意"的使用与"不同。 over" ="对于Id字段,因为我想要" DBNull.Value == DBNull.Value"返回真实。
我的问题:
这可能与Linq的内存DataTables有关吗? Linq如何在这些查询中处理DBNull.Value比较?
答案 0 :(得分:0)
Linq会正确地将DBNull.Value
与另一个DBNull.Value
匹配。我相信那是你的问题而不是加入第二张儿童表,因为这是微不足道的
DataTable parent = new DataTable();
parent.Columns.Add("Id1", typeof(string));
parent.Columns.Add("Id2", typeof(string));
DataRow r1 = parent.NewRow();
r1["Id1"] = "1";
r1["Id2"] = DBNull.Value;
parent.Rows.Add(r1);
DataRow r3 = parent.NewRow();
r3["Id1"] = "1";
r3["Id2"] = "2";
parent.Rows.Add(r3);
DataTable child1 = new DataTable();
child1.Columns.Add("Id1", typeof(string));
child1.Columns.Add("Id2", typeof(string));
child1.Columns.Add("BeginDate", typeof(DateTime));
child1.Columns.Add("SomeData", typeof(float));
DataRow r2 = child1.NewRow();
r2["Id1"] = "1";
r2["Id2"] = DBNull.Value;
child1.Rows.Add(r2);
DataRow r4 = child1.NewRow();
r4["Id1"] = "1";
r4["Id2"] = "2";
child1.Rows.Add(r4);
var dataToReturn =
from
p in parent.AsEnumerable()
join c1 in child1.AsEnumerable()
on new { Id1 = p["Id1"], Id2 = p["Id2"] }
equals new { Id1 = c1["Id1"], Id2 = c1["Id2"] }
select new
{
Id1 = p["Id1"],
Id2 = p["Id2"]
};
foreach(var l in dataToReturn)
{
Console.WriteLine(l.Id1 + "|" + l.Id2);
}
Console.ReadKey();
输出:
1|
1|2