使用LINQ Average()方法处理null结果

Mag*_*pie 14 .net c# linq

我是LINQ的新手,我正在尝试从表格到图表创建一些数据点.此表中的三个重要字段是id,时间和值.我正在编写一个查询来获取所选id的设定时间内的平均值.我写的LINQ如下:

var value = (from t in _table
             where t.Id == id
                 && t.Time >= intervalStartTime
                 && t.Time <= intervalEndTime
             select t.Value).Average();
Run Code Online (Sandbox Code Playgroud)

但是,这会在运行时崩溃:

"无法将null值分配给类型为System.Decimal的成员,这是一个不可为空的值类型.."

在某些时间间隔没有数据,所以SQL LINQ生成返回null,我希望COALESCED为0但反而崩溃了应用程序.有没有办法编写这个LINQ查询,以便能够正确处理这个问题?

表定义使事情更清晰:

[Serializable]
[Table(Name = "ExampleTable")]
public class ExampleTable
{
    [Column(Name = "Id")]
    public int Id { get; set; }

    [Column(Name = "Time")]
    public DateTime Time { get; set; }

    [Column(Name = "Value")]
    public int Value{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)

Rub*_*ben 20

我想你想要的

var value = (from t in _table
             where t.Id == id
                && t.Time >= intervalStartTime
                && t.Time <= intervalEndTime
             select (int?)t.Value).Average()
Run Code Online (Sandbox Code Playgroud)

这样,你得到一个double?后卫,而没有(int?)施法,你需要得到一个double后卫,这是不可能的null.

这是因为签名

double Enumerable.Average(IEnumerable<int> source)
double? Enumerable.Average(IEnumerable<int?> source)
Run Code Online (Sandbox Code Playgroud)

现在,要获得平均值0而不是null,您需要将合并运算符放在最后

var value = (from t in _table
             where t.Id == id
                && t.Time >= intervalStartTime
                && t.Time <= intervalEndTime
             select (int?)t.Value).Average() ?? 0.0;
Run Code Online (Sandbox Code Playgroud)

恕我直言,这是一个非常可怕的Enumerable/ Queryableclass 设计; 为什么不能Average(IEnumerable<int>)回来double?,为什么只为了Average(IEnumerable<int?>)


Jon*_*eet 17

编辑:完全改变:)

好的,这个怎么样:

var value = (from t in _table
             where t.Id == id
                 && t.Time >= intervalStartTime
                 && t.Time <= intervalEndTime
             select t.Value).DefaultIfEmpty().Average()
Run Code Online (Sandbox Code Playgroud)

我认为这在逻辑上是你想要的 - 将{}改为{0},这样可以实现所有平均值.我不知道它是否会在SQL方面做你想做的事情.