所以,我有一个函数返回数据以供在GridView中使用。完成需要很长时间(约25秒)。我认为我写的非常糟糕,我需要优化它以便它运行得更快。
这是代码:
var pingresult = from p in db.GetTable<tblTBHealthPing>()
group p by p.ComputerAsset into g
select g.OrderByDescending(t => t.HealthPingTime).FirstOrDefault();
var healthresult = from p in db.GetTable<tblTBHealthHeartbeat>()
group p by p.ComputerAsset into g
select g.OrderByDescending(t => t.HealthHeartbeatTime).FirstOrDefault();
var query = (from t in TrackingBoardPCs()
where t.TrackingGroup == groupName
select new TrackingComputer
{
ComputerName = t.ComputerAsset,
IPAddress = t.ComputerIP,
Location = t.Location,
Pingable = (from p in pingresult where p.ComputerAsset == t.ComputerAsset select p.HealthPingResult).FirstOrDefault() ?? false,
PingTime = (from p in pingresult where p.ComputerAsset == t.ComputerAsset select p.HealthPingTime).FirstOrDefault() ?? DateTime.Now.AddDays(-100),
Username = (from p in healthresult where p.ComputerAsset == t.ComputerAsset select p.HealthCurrentUser).FirstOrDefault(),
CurrentWindow = (from p in healthresult where p.ComputerAsset == t.ComputerAsset select p.HealthCurrentWindow).FirstOrDefault(),
Uptime = (from p in healthresult where p.ComputerAsset == t.ComputerAsset select p.HealthUptime).FirstOrDefault()
}).OrderBy(t => t.Pingable);
return query;
这可能是一种更好的方法,即删除前两个变量(pingresult和healthresult)并以某种方式将它们引入主查询,但我不知道如何。任何帮助都会很棒:)
答案 0 :(得分:0)
我认为,您的pingresult
和healthresult
类型iqueryable
。所以你的代码将db
转到这个小道:
PingTime = (from p in pingresult where p.ComputerAsset == t.ComputerAsset select p.HealthPingTime).FirstOrDefault() ?? DateTime.Now.AddDays(-100),
Username = (from p in healthresult where p.ComputerAsset == t.ComputerAsset select p.HealthCurrentUser).FirstOrDefault(),
CurrentWindow = (from p in healthresult where p.ComputerAsset == t.ComputerAsset select p.HealthCurrentWindow).FirstOrDefault(),
Uptime = (from p in healthresult where p.ComputerAsset == t.ComputerAsset select p.HealthUptime).FirstOrDefault()
如果您使用ToList()
数据获取本地内存并且应该更快。也许你可以像这样使用:
var pingresult = from p in db.GetTable<tblTBHealthPing>()
group p by p.ComputerAsset into g
select g.OrderByDescending(t => t.HealthPingTime).ToList().FirstOrDefault();//ToList() gets data from db to local memory
var healthresult = from p in db.GetTable<tblTBHealthHeartbeat>()
group p by p.ComputerAsset into g
select g.OrderByDescending(t => t.HealthHeartbeatTime).ToList().FirstOrDefault();//ToList() gets data from db to local memory
答案 1 :(得分:0)
将子查询嵌入主查询中绝对是个好主意。
执行此操作时,您会注意到TrackingBoardPCs
始终加入了ComputerAsset
记录,因此他们不需要groupby
该字段。
这是IMO的等效查询:
var query =
from t in TrackingBoardPCs()
where t.TrackingGroup == groupName
join p in db.GetTable<tblTBHealthPing>() on t.ComputerAsset equals p.ComputerAsset
into pingInfo
join h in db.GetTable<tblTBHealthHeartbeat>() on t.ComputerAsset equals h.ComputerAsset
into heartbeatInfo
let p = pingInfo.OrderByDescending(p => p.HealthPingTime).FirstOrDefault()
let h = heartbeatInfo.OrderByDescending(p => p.HealthHeartbeatTime).FirstOrDefault()
let tc = new TrackingComputer
{
ComputerName = t.ComputerAsset,
IPAddress = t.ComputerIP,
Location = t.Location,
Pingable = p.HealthPingResult ?? false,
PingTime = p.HealthPingTime ?? DateTime.Now.AddDays(-100),
Username = h.HealthCurrentUser,
CurrentWindow = h.HealthCurrentWindow,
Uptime = h.HealthUptime
}
order by tc.Pingable
select tc;