我有一个父表,parentTable,在childTable中可能有也可能没有子项。我希望得到任何给定父母子女的平均完成百分比,以及他们所在的孩子的MAX(到期)(日期)。我的SQL是这样的:
SELECT parentRecord_id, assigned_to,
(SELECT avg(complete)
FROM childTable
WHERE parent_id = parentRecord_id
and deleted IS NULL
GROUP BY parent_id),
(SELECT max(due)
FROM childTable
WHERE parent_id = parentRecord_id
and deleted IS NULL
GROUP BY parent_id
)
FROM parentTable s
WHERE s.deleted IS NULL and assigned_to IS NOT NULL
我的结果集为我提供了具有正确值和最大值的行,或者为null。在这个例子中,我必须进行后续处理,所以如果我通过DataTable行进行foreach,我可以忽略空值。但是我试图在Linq中这样做,并且无法弄清楚如何避免System.InvalidOperationException,其中Linq试图将null转换为double。这是我到目前为止所尝试过的。
var query8 = from s in db.parentTable
where s.deleted == null
select new
{
ID = s.assigned_to,
Average =
((from t in db.childTable
where t.parent_id == s.strategy_id
group t by new { t.parent_id } into g
select new
{
a0 = g.Average(f0 => f0.complete )
}).FirstOrDefault().a0)
};
foreach (var itm in query8)
{
Console.WriteLine(String.Format("User id:{0}, Average: {1}", itm.ID, itm.Average));
}
这是我的问题。如何获取查询来处理平均完成或最大到期(日期)为空的返回行?
答案 0 :(得分:0)
您可以过滤掉值为空的记录(按其他条件),或者如果要包含它们,请执行以下操作:
a0 = g.Average(f0 => f0.complete.HasValue? f0.complete: 0 )
答案 1 :(得分:0)
我会在调用Average / Max之前将列表转换为可以为空的double:
var query8 =
from s in db.parentTable
where s.deleted == null
select new
{
ID = s.assigned_to,
Average =
from t in db.childTable
where t.parent_id == s.strategy_id
group t by t.parent_id into g
select g.Cast<double?>().Average(f0 => f0.complete)
};
答案 2 :(得分:0)
假设complete是Nullable,你应该能够:
var query8 = from s in db.parentTable
where s.deleted == null
select new
{
ID = s.assigned_to,
Average =
((from t in db.childTable
where t.parent_id == s.strategy_id
&& s.complete.HasValue()
group t by new { t.parent_id } into g
select new
{
a0 = g.Average(f0 => f0.complete )
}).FirstOrDefault().a0)
};
答案 3 :(得分:0)
感谢所有回复的人。
我无法解决基本查询的null匿名问题,但是在childTable中添加连接消除了空值。
另一个解决方案是在g.DefaultIfEmpty子句中使用from x。
var query8 =
from st in db.tableParent
select new { Ass = st.assigned_to ,
Avg =
(from ta in db.tableChild
group ta by ta.parent_id into g
from x in g.DefaultIfEmpty()
select g.Average((f0=>f0.complete))).FirstOrDefault()
};