Gra*_*ark 5 c# sql linq average aggregates
我正在尝试将一些SQL查询转换为Linq,以避免多次访问数据库.
我正在尝试转换的旧SQL:
SELECT
AVG(CAST(DATEDIFF(ms, A.CreatedDate, B.CompletedDate) AS decimal(15,4))),
AVG(CAST(DATEDIFF(ms, B.CreatedDate, B.CompletedDate) AS decimal(15,4)))
FROM
dbo.A
INNER JOIN
dbo.B ON B.ParentId = A.Id
Run Code Online (Sandbox Code Playgroud)
所以我创建了两个C#类:
class B
{
public Guid Id { get; set; }
public DateTime CreatedDate { get; set; }
public DateTime CompletedDate { get; set; }
}
class A
{
public Guid Id { get; set; }
public DateTime CreatedDate { get; set; }
public List<B> BList { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我有一个List<A>我想查询的对象.它是从数据库填充的,因此列表中的每个A都有一个负载为Bs的子列表.我想使用Linq-to-objects来查询此列表.
所以我需要使用Linq来获得A开始和孩子Bs完成之间的平均时间,以及每个B开始和完成之间的平均时间.我没有写原始的SQL所以我不完全确定它做了它应该做的!
我有几个这些平均值要计算,所以我想在一个神奇的Linq查询中完成它们.这可能吗?
更有趣的问题是如何在服务器上执行此类操作,例如,将以下查询转换为LINQ to SQL.
var q = from single in Enumerable.Range(1, 1)
let xs = sourceSequence
select new
{
Aggregate1 = xs.Sum(),
Aggregate2 = xs.Average(),
// etc
};
Run Code Online (Sandbox Code Playgroud)
但是,如果您使用LINQ to Objects,那么尝试将其塞入一个查询是毫无意义的.只需单独编写聚合:
var aggregate1 = xs.Sum();
var aggregate2 = xs.Average();
// etc
Run Code Online (Sandbox Code Playgroud)
换一种说法:
var xs = from a in listOfAs
from b in a.Bs
select new { A=a, B=b };
var average1 = xs.Average(x => (x.B.Completed - x.A.Created).TotalSeconds);
var average2 = xs.Average(x => (x.B.Completed - x.B.Created).TotalSeconds);
Run Code Online (Sandbox Code Playgroud)
我明白了吗?
编辑:大卫B回答同样的问题.我忘了将TimeSpan转换为Average方法支持的简单数字类型.使用TotalMilliseconds/Seconds/Minutes或任何适当的比例.