使用 LINQ 进行两个查询的完全外部联接的更好方法? C#
Better way of making a Full Outer Join using LINQ for two Queries? C#
我想知道是否有更简洁的代码来执行此 LINQ 语句,因为一旦我将这些查询转移到我的实际程序中,我将查询更多变量([=48= 的其他属性) ] table).
来自 LINQpad 的 LINQ 语句:
// Displaying the Child (with their dialects)
var query = (
from c in child_t
join cd in tn_child_dialect_t on c.child_id equals cd.child_id into tcdGroup
from a in tcdGroup.DefaultIfEmpty()
join d in lu_dialect_t on a.dialect_id equals d.dialect_id into dGroup
from b in dGroup.DefaultIfEmpty()
group c by new { c.child_id, c.last_name, b.name } into grp
select new
{
child_id = grp.Key.child_id,
last_name = grp.Key.last_name,
dialects = grp.Key.name,
});
var query2 = (from item in query.ToList()
group item by new { item.child_id } into grp
select new
{
child_id = grp.FirstOrDefault().child_id,
last_name = grp.FirstOrDefault().last_name,
dialects = string.Join(", " , grp.Select(d=>d.dialects)),
}).ToList();
// Displaying the Child (with their vaccinations)
var query3 =
from c in child_t
join cv in tn_child_vaccination_t on c.child_id equals cv.child_id into tcvGroup
from n in tcvGroup.DefaultIfEmpty()
join v in lu_vaccination_t on n.vaccination_id equals v.vaccination_id into d2Group
from m in d2Group.DefaultIfEmpty()
//where (c.child_id == 1)
group c by new { c.child_id, c.last_name, m.name } into grp
select new
{
child_id = grp.Key.child_id,
last_name = grp.Key.last_name,
vaccinations = grp.Key.name,
};
var query4 = (from item in query3.ToList()
group item by new { item.child_id } into grp
select new
{
child_id = grp.FirstOrDefault().child_id,
last_name = grp.FirstOrDefault().last_name,
vaccinations = string.Join(", " , grp.Select(d=>d.vaccinations)),
}).ToList();
/* Fuller Outer Join query2 and query4*/
var childIDs = query2.Select(x => x.child_id).Union(query4.Select(x => x.child_id));
var q = from id in childIDs
join d in query2 on id equals d.child_id into firstGroup from n in firstGroup.DefaultIfEmpty()
join v in query4 on id equals v.child_id into secondGroup from m in secondGroup.DefaultIfEmpty()
//where firstGroup.Any() ^ secondGroup.Any()
select new {
id = n.child_id,
dialects = n.dialects,
vaccinations = m.vaccinations
};
Console.WriteLine(q);
这是 运行:
时的样子
其他相关table的描述:
- child_t = Table 包含 children
的所有信息
- tn_child_dialect_t = 交易 table 获得 'child_t' 的 child_id 和 [=] 的 dialect_id 45=]
- lu_dialect_t = Table 可以选择的方言
- tn_child_vaccination_t = 交易 table 得到 'child_t' 的 child_id 和 [=] 的 vaccination_id 47=]
- lu_vaccination_t = Table可以选择的疫苗
尝试这样的事情:
var query =
(from child in child_t
join tmp_child_dialect in tn_child_dialect_t
on child.child_id equals tmp_child_dialect.child_id into tmp_child_dialect_group
from child_dialect in tmp_child_dialect_group.DefaultIfEmpty()
join tmp_dialect in lu_dialect_t
on child_dialect.dialect_id equals tmp_dialect.dialect_id into tmp_dialect_group
from dialect in tmp_dialect_group.DefaultIfEmpty()
join tmp_child_vaccination in tn_child_vaccination_t
on child.child_id equals tmp_child_vaccination.child_id into tmp_child_vaccination_group
from child_vaccination in tmp_child_vaccination_group.DefaultIfEmpty()
join tmp_vaccination in lu_vaccination_t
on child_vaccination.vaccination_id equals tmp_vaccination.vaccination_id into tmp_vaccination_group
from vaccination in tmp_vaccination_group.DefaultIfEmpty()
select new { ChildId = child.child_id,
DialectName = dialect.name,
VaccinationName = vaccination.name }
)
.GroupBy(x => x.ChildId, (key, group) => new
{
ChildId = key,
Dialects = group.Select(x => x.DialectName)
.Where(x => x != null)
.Distinct(),
Vaccinations = group.Select(x => x.VaccinationName)
.Where(x => x != null)
.Distinct()
});
我想知道是否有更简洁的代码来执行此 LINQ 语句,因为一旦我将这些查询转移到我的实际程序中,我将查询更多变量([=48= 的其他属性) ] table).
来自 LINQpad 的 LINQ 语句:
// Displaying the Child (with their dialects)
var query = (
from c in child_t
join cd in tn_child_dialect_t on c.child_id equals cd.child_id into tcdGroup
from a in tcdGroup.DefaultIfEmpty()
join d in lu_dialect_t on a.dialect_id equals d.dialect_id into dGroup
from b in dGroup.DefaultIfEmpty()
group c by new { c.child_id, c.last_name, b.name } into grp
select new
{
child_id = grp.Key.child_id,
last_name = grp.Key.last_name,
dialects = grp.Key.name,
});
var query2 = (from item in query.ToList()
group item by new { item.child_id } into grp
select new
{
child_id = grp.FirstOrDefault().child_id,
last_name = grp.FirstOrDefault().last_name,
dialects = string.Join(", " , grp.Select(d=>d.dialects)),
}).ToList();
// Displaying the Child (with their vaccinations)
var query3 =
from c in child_t
join cv in tn_child_vaccination_t on c.child_id equals cv.child_id into tcvGroup
from n in tcvGroup.DefaultIfEmpty()
join v in lu_vaccination_t on n.vaccination_id equals v.vaccination_id into d2Group
from m in d2Group.DefaultIfEmpty()
//where (c.child_id == 1)
group c by new { c.child_id, c.last_name, m.name } into grp
select new
{
child_id = grp.Key.child_id,
last_name = grp.Key.last_name,
vaccinations = grp.Key.name,
};
var query4 = (from item in query3.ToList()
group item by new { item.child_id } into grp
select new
{
child_id = grp.FirstOrDefault().child_id,
last_name = grp.FirstOrDefault().last_name,
vaccinations = string.Join(", " , grp.Select(d=>d.vaccinations)),
}).ToList();
/* Fuller Outer Join query2 and query4*/
var childIDs = query2.Select(x => x.child_id).Union(query4.Select(x => x.child_id));
var q = from id in childIDs
join d in query2 on id equals d.child_id into firstGroup from n in firstGroup.DefaultIfEmpty()
join v in query4 on id equals v.child_id into secondGroup from m in secondGroup.DefaultIfEmpty()
//where firstGroup.Any() ^ secondGroup.Any()
select new {
id = n.child_id,
dialects = n.dialects,
vaccinations = m.vaccinations
};
Console.WriteLine(q);
这是 运行:
时的样子其他相关table的描述:
- child_t = Table 包含 children 的所有信息
- tn_child_dialect_t = 交易 table 获得 'child_t' 的 child_id 和 [=] 的 dialect_id 45=]
- lu_dialect_t = Table 可以选择的方言
- tn_child_vaccination_t = 交易 table 得到 'child_t' 的 child_id 和 [=] 的 vaccination_id 47=]
- lu_vaccination_t = Table可以选择的疫苗
尝试这样的事情:
var query =
(from child in child_t
join tmp_child_dialect in tn_child_dialect_t
on child.child_id equals tmp_child_dialect.child_id into tmp_child_dialect_group
from child_dialect in tmp_child_dialect_group.DefaultIfEmpty()
join tmp_dialect in lu_dialect_t
on child_dialect.dialect_id equals tmp_dialect.dialect_id into tmp_dialect_group
from dialect in tmp_dialect_group.DefaultIfEmpty()
join tmp_child_vaccination in tn_child_vaccination_t
on child.child_id equals tmp_child_vaccination.child_id into tmp_child_vaccination_group
from child_vaccination in tmp_child_vaccination_group.DefaultIfEmpty()
join tmp_vaccination in lu_vaccination_t
on child_vaccination.vaccination_id equals tmp_vaccination.vaccination_id into tmp_vaccination_group
from vaccination in tmp_vaccination_group.DefaultIfEmpty()
select new { ChildId = child.child_id,
DialectName = dialect.name,
VaccinationName = vaccination.name }
)
.GroupBy(x => x.ChildId, (key, group) => new
{
ChildId = key,
Dialects = group.Select(x => x.DialectName)
.Where(x => x != null)
.Distinct(),
Vaccinations = group.Select(x => x.VaccinationName)
.Where(x => x != null)
.Distinct()
});