我是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方面做你想做的事情.