Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取DateTime为空的计算项的平均值_C#_Sql_Linq_Linq To Sql - Fatal编程技术网

C# 获取DateTime为空的计算项的平均值

C# 获取DateTime为空的计算项的平均值,c#,sql,linq,linq-to-sql,C#,Sql,Linq,Linq To Sql,糟糕的标题,我知道 这很管用,给了我想要的东西,但我知道一定有更好的方法: var query = (from a in DB where a.Date.HasValue select a).AsEnumerable(); double avg = (from a in query select (a.Date.Value.Subtract(a.OtherDate).Days).Average(); 基本上,a.

糟糕的标题,我知道

这很管用,给了我想要的东西,但我知道一定有更好的方法:

var query = (from a in DB
             where a.Date.HasValue
             select a).AsEnumerable();

double avg = (from a in query
              select (a.Date.Value.Subtract(a.OtherDate).Days).Average();
基本上,a.Date是一个可为空的datetime,我只想在a.Date存在的情况下(否则计算不起作用)得到(a.Date-a.OtherDate)的平均值

像这样的事情是行不通的:

double avg = (from a in DB
              where a.Date.HasValue
              select a.Date.Value.Subtract(a.OtherDate).Days).Average();
我知道我见过类似的问题,解决方案是显式地将可空字段设置为可空datetime,从而使平均方法工作。我没有看到过可空字段是这样计算的一部分

提前谢谢

编辑:要澄清一点,让我告诉你Ben的解决方案及其产生的错误消息。我必须承认我遗漏了另一部分…答:OtherDate实际上有点棘手…让我举例说明:

var avg = DB.Where(a => a.Date.HasValue)
            .Where(a => a.ForeignKeyReference.Date.HasValue)
            .Select(a => a.Date.Value.Subtract(a.ForeignKeyReference.Date.Value).Days)
            .Average();
…以及错误:

InvalidOperationException:无法将表达式“Table(DB).Where(a=>a.Date.HasValue).Where(a=>a.ForeignKeyReference.Date.HasValue).选择(a=>a.Date.Value.Subtract(a.ForeignKeyReference.Date.Value).Days()”转换为SQL,无法将其视为本地表达式

似乎“Subtract”方法或“Days”属性没有转换为SQL。我的第一个示例有效,因为第二个查询是LINQ to对象。有人知道是否有一种方法可以将LINQ查询转换为SQL吗?

如何

double AvgDays = dates.Where(d => d.Date.HasValue)
                        .Average(dd => (dd.Date.Value-dd.OtherDate).Days);
但也许像这样的东西更有用

var ticks = (long)dates.Where(d => d.Date.HasValue)
                        .Average(dd => (dd.Date.Value - dd.OtherDate).Ticks);

var avg = new TimeSpan(ticks);

Console.WriteLine("It's " + avg.Days + " days and " + avg.Hours + " hours and " + avg.Seconds + " seconds.");

像这样的东西确实起到了作用-我已经使用3.5 sp1框架验证了输出是正确的:

var avg = DB
    .Where(a => a.Date.HasValue)
    .Select(a => a.Date.Value.Subtract(a.OtherDate).Days)
    .Average();

Where()运算符确保将带有.Date且值为空的任何元素从平均值中排除;这是您表示想要的行为,对吗?

可能应该更仔细地阅读错误消息。看起来“Subtract”方法没有到SQL的转换,但实际上您可以简单地从一个日期减去另一个日期来创建日期时间,如下所示:

var query = from a in DB
            select (a.Date.Value - a.ForeignKeyReference.Date.Value);
这意味着解决方案是:

var query = (from a in DB
             where a.Date.HasValue
             where a.ForeignKeyReference.Date.HasValue
             let ts = (TimeSpan)(a.Date.Value - a.ForeignKeyReference.Value)
             select ts.Days).Average();

Jonas Elfström的回答是正确的,我只是补充一下,因为它触及了问题的实际原因。

你能解释一下为什么像这样的事情不起作用吗?我的意思是,对于第二个linq查询,您面临什么问题?编译器错误?运行时错误?查询返回的值错误?这适用于LINQ to对象,但正如我的回答所示,LINQ中没有将.Subtract()转换为SQL。