【问题标题】:GroupJoin, SelectMany, GroupBy and SumGroupJoin、SelectMany、GroupBy 和 Sum
【发布时间】:2018-02-27 17:25:29
【问题描述】:

我正在尝试使用 GroupJoin 和 SelectMany 在 linq 中执行“左外连接”,但我还想使用 GroupBy 和 Sum 聚合结果。

但是当我执行下面的代码时,我得到:

System.NotSupportedException: '无法在 LINQ to Entities 查询中构造实体或复杂类型'...tableB'。'

Repo<tableA>().All()
    .Where(i =>
        (i.Date >= dateF && i.Date <= dateT)
        &&
        i.EndOfMonth
    )
    .GroupJoin(
        Repo<tableB>().All().Where(i => (i.fieldX = ...somevalue... )), 
        dt => dt.DayIndex, scd => scd.DayIndex, (dt, scd) =>
            new {
                dt = dt,
                scd = scd,
            }
    )
    .SelectMany(
        jn => jn.scd.DefaultIfEmpty( new tableB { Count1 = 0, Count2 = 0 }), // runtime error here
        (dt,scd) => new { dt=dt.dt, scd = scd}
        )
    .GroupBy(i => i.dt)
    .Select(i => new CountListItem
    {
        Date = i.Key.Date,
        CountField1 = i.Sum(o => o.scd.Count1),
        CountField2 = i.Sum(p => p.scd.Count2)
     })
     .OrderBy(i => i.Date)
     .ToList()

当我只是做DefaultIfEmpty() 时,我得到了错误:

System.InvalidOperationException:“转换为值类型“System.Int32”失败,因为具体化值为 null。结果类型的泛型参数或查询必须使用可为空的类型。'

我假设,我必须承认,这是因为 Sum 遇到空值。

我试过i.Sum(o =&gt; o.scd.Count1 ?? 0,但它说:

运算符'??'不能应用于“int”和“int”类型的操作数 [原文]

我也试过DefaultIfEmpty(new { Count1 = 0, Count2 =0}),但这给了我>

...无法推断类型。

我怎样才能让它工作?

【问题讨论】:

    标签: c# entity-framework linq entity-framework-6


    【解决方案1】:

    避免第一个异常很容易 - 只需将标准模式用于 left outer join 和无参数 DefaultIfEmpty()

    第二个问题源于 SQL 和 LINQ (C#) 查询数据类型之间的差异。 SQL 查询本身支持 NULL 值,即使源表达式不可为空,也可以返回 NULL。正如您在上次尝试中注意到的那样,LINQ(尤其是 C# 编译器)对这种语法并不满意。

    诀窍是使用 C# 强制转换运算符将不可空类型提升为可空类型,然后然后将空合并运算符应用于结果表达式:

    CountField1 = i.Sum(o => (int?)o.scd.Count1 ?? 0),
    CountField2 = i.Sum(o => (int?)o.scd.Count2 ?? 0),
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-19
      • 1970-01-01
      • 2014-10-22
      • 2019-09-29
      • 2023-03-30
      • 2019-02-02
      相关资源
      最近更新 更多