0

我有一个父表 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

我的结果集为我提供了平均值和最大值的正确值或空值的行。在这种情况下,我必须进行后续处理,因此如果我正在通过 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));
    }

这是我的问题。如何让查询处理那些平均完成或最大到期(日期)为空的返回行?

4

4 回答 4

0

感谢所有回复的人。

我无法通过基本查询解决空匿名问题,但是向 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()
     };
于 2013-04-03T11:52:17.107 回答
0

您可以过滤掉值为空的记录(通过另一个条件),或者如果您想包含它们,请执行以下操作:

a0 = g.Average(f0 => f0.complete.HasValue? f0.complete: 0 )
于 2013-04-02T15:36:06.193 回答
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)
    };
于 2013-04-02T15:36:30.437 回答
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) 
                       };
于 2013-04-02T15:38:31.623 回答