C# LINQ取查询中多个字段的平均值

C# LINQ取查询中多个字段的平均值,c#,sql,linq,C#,Sql,Linq,我有一个如下的问题 select q1, q2, q3, q4, average from results var query = from T in db.results select new ResultsCustom { q1, q2, q3, q4 average = ((doub

我有一个如下的问题

select q1, q2, q3, q4, average from results
var query = from T in db.results
                        select new ResultsCustom
                        {
                            q1, q2, q3, q4
                            average = ((double)(T.q1 ?? 0.0)
                                + (double)(T.q2 ?? 0.0)
                                + (double)(T.q3 ?? 0.0)
                                + (double)(T.q4 ?? 0.0)
                                ) / 4};
我需要计算每行平均列中q1到q5的平均值。我有以下几点

select q1, q2, q3, q4, average from results
var query = from T in db.results
                        select new ResultsCustom
                        {
                            q1, q2, q3, q4
                            average = ((double)(T.q1 ?? 0.0)
                                + (double)(T.q2 ?? 0.0)
                                + (double)(T.q3 ?? 0.0)
                                + (double)(T.q4 ?? 0.0)
                                ) / 4};
问题是,q1到q4可能为空,这会使平均值偏离。如果它们为空,我不想将它们包括在平均值计算中。我在想,如果有空值,我可以减少计数。有更好的方法吗?

double-GetAverage(T)
double GetAverage(T)
{
    List<double> list = new List<double>();
    if (T.q1 != null) list.Add(T.q1);
    if (T.q2 != null) list.Add(T.q2);
    if (T.q3 != null) list.Add(T.q3);
    if (T.q4 != null) list.Add(T.q4);
    return list.Average();
}
{ 列表=新列表(); 如果(T.q1!=null)list.Add(T.q1); 如果(T.q2!=null)列表。添加(T.q2); 如果(T.q3!=null)list.Add(T.q3); 如果(T.q4!=null)列表。添加(T.q4); 返回列表。平均值(); }
你不是在计算平均值。只需使用标准公式
sum/count

...
let sum = q1.GetValueOrDefault() + q2.GetValueOrDefault() + ...
let count = (q1 != null ? 1 : 0) + ...
let avg = sum / count
...

您可能还需要定义如果
count==0

这将无法转换为SQL,但您可以执行以下操作:

var query = from T in db.results
            select new ResultsCustom
            {
                q1, q2, q3, q4
                average = (new double?[] { T.q1, T.q2, T.q3, T.q4 }).Average()
            };
因为
Average()
将忽略空值

要获得结果并在Linq中对对象进行平均,请执行以下操作:

var query = (from T in db.results select new {q1, q2, q3, q4}).AsEnumerable()
            .Select(r => new ResultsCustom
                 {
                     r.q1, r.q2, r.q3, r.q4,
                     average = (new double?[] { r.q1, r.q2, r.q3, r.q4 }).Average()
                 }
             );

您可以概括如下(未经测试):

double-GetAverage(List-doublesList)
{
var list=doublesList.Where(x=>x!=null).ToList();
返回列表。平均值();
}

它返回任意长度的
双倍
列表的平均值,忽略
空值
,将过程与数据采集分开。

我认为关键是用0替换空值,因此:list.Add(T.q1±0)等(否则,您可以对枚举表本身调用average()还应指出,如果q1-q4中的所有值都为空,则
平均值将为空。计数必须是值的数目,而不取决于值是否为空。@Dennis_E在他的问题中建议空值不算作值。@Dennis_E“如果它们为空,我不想将它们包括在平均值计算中”-我将其翻译为“取所有非空值的平均值”。同意@Dennis_E,否则他不会将其除以4。我不确定我是否理解。如果他不想包括它们,那么计数就不能是常数。否则的话,他的平均成绩是零。他已经在这个问题上了。