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

z5btuh9x  于 2024-01-03  发布在  其他
关注(0)|答案(5)|浏览(192)

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

  1. var value = (from t in _table
  2. where t.Id == id
  3. && t.Time >= intervalStartTime
  4. && t.Time <= intervalEndTime
  5. select t.Value).Average();

字符串
然而,这在运行时崩溃,并导致:
“无法将空值分配给类型为System. Declaration的成员,因为该类型是不可空的值类型。”
在某些时间间隔内没有数据,因此SQL LINQ生成的返回null,我希望将其COALESCED为0,但却使应用程序崩溃。有没有一种方法可以编写此LINQ查询以正确处理此问题?
表的定义,使事情更清楚:

  1. [Serializable]
  2. [Table(Name = "ExampleTable")]
  3. public class ExampleTable
  4. {
  5. [Column(Name = "Id")]
  6. public int Id { get; set; }
  7. [Column(Name = "Time")]
  8. public DateTime Time { get; set; }
  9. [Column(Name = "Value")]
  10. public int Value{ get; set; }
  11. }

omtl5h9j

omtl5h9j1#

我觉得你想

  1. var value = (from t in _table
  2. where t.Id == id
  3. && t.Time >= intervalStartTime
  4. && t.Time <= intervalEndTime
  5. select (int?)t.Value).Average()

字符串
这样,你得到一个double?,而没有(int?)转换,你需要得到一个double,它不能是null
这是因为签名

  1. double Enumerable.Average(IEnumerable<int> source)
  2. double? Enumerable.Average(IEnumerable<int?> source)


现在,为了得到平均值0而不是null,需要将合并运算符放在末尾

  1. var value = (from t in _table
  2. where t.Id == id
  3. && t.Time >= intervalStartTime
  4. && t.Time <= intervalEndTime
  5. select (int?)t.Value).Average() ?? 0.0;


恕我直言,这是Enumerable/Queryable类的一个非常糟糕的设计;为什么Average(IEnumerable<int>)不能返回double?,为什么只返回Average(IEnumerable<int?>)

展开查看全部
km0tfn4u

km0tfn4u2#

好吧,不如这样:

  1. var value = (from t in _table
  2. where t.Id == id
  3. && t.Time >= intervalStartTime
  4. && t.Time <= intervalEndTime
  5. select t.Value).DefaultIfEmpty().Average()

字符串
我相信这是 * 逻辑上 * 您想要的-将{}更改为{0},因此可以实现所有平均值。但我不知道它是否会在SQL方面实现您想要的功能。

h9vpoimq

h9vpoimq3#

编辑:总返工
尝试先将值强制转换为nullable

  1. var value = (from t in _table
  2. where t.Id == id
  3. && t.Time >= intervalStartTime
  4. && t.Time <= intervalEndTime
  5. select ((int?)t.Value) ?? 0).Average()

字符串

vkc1a9a2

vkc1a9a24#

尝试以下操作。它将简单地跳过查询返回的所有空项。

  1. var value = (from t in _table
  2. where t != null
  3. where t.Id == id
  4. && t.Time >= intervalStartTime
  5. && t.Time <= intervalEndTime
  6. select t.Value).Average();

字符串
如果你想显式地将null项视为零,那么简单地使用 * 条件运算符 * 就可以完成这项工作:

  1. var value = (from t in _table
  2. where t == null ||
  3. (t.Id == id
  4. && t.Time >= intervalStartTime
  5. && t.Time <= intervalEndTime)
  6. select t == null ? 0 : t.Value).Average();

展开查看全部
n3schb8v

n3schb8v5#

你能在初始查询中使用一个临时变量吗?
例如:

  1. var temp = (from t in _table
  2. where t.Id == id
  3. && t.Time >= intervalStartTime
  4. && t.Time <= intervalEndTime
  5. select t.Value) ?? new List<int>() {0};
  6. var value = temp.Average();

字符串
不知道这是否有帮助。

相关问题