我的模特有:
DeviceStatus
附加到一个强制性Device
Device
附加到一个强制性Panel
当我查询DeviceStatus
时,我需要在查询结果中附加Device
和Panel
。
... DeviceStatus.Device在查询结果中为空。
这是Linq查询:
using (var actiContext = new ActigraphyContext())
{
var todayStatus =
from s in actiContext.DeviceStatus.Include(s1 => s1.Device.Panel)
where DbFunctions.TruncateTime(s.TimeStamp) == DbFunctions.TruncateTime( DateTimeOffset.Now)
&& s.Device.Panel.Mac == mac
&& (s.Device.Ty == 4 || s.Device.Ty == 9)
select s;
// var tempList = todayStatus.toList();
var todayLastStatus =
from s in todayStatus.Include(s1 => s1.Device.Panel)
let lastTimeStamp = todayStatus.Max(s1 => s1.TimeStamp)
where s.TimeStamp == lastTimeStamp
select s;
var requestResult = todayLastStatus.FirstOrDefault();
return requestResult;
}
如果我取消注释未使用tempList的行// var tempList = todayStatus.toList();
,它可以正常工作:requestResult.Device已设置!
但不好的一面是今天,Status.toList会触发一个带来大量数据的请求。
那么如何使用相关对象获取DeviceStatus?
注意:后面的数据库是SQL Server 2012
答案 0 :(得分:2)
当您通过LINQ查询调用Include()时,它会执行Eagerly Loading。
如MSDN中所述: 预先加载是一种过程,其中对一种类型的实体的查询也将相关实体作为查询的一部分加载。通过使用Include方法实现预先加载。 读取实体时,将同时检索相关数据。这通常会导致单个连接查询检索所需的所有数据。您可以使用Include方法指定预先加载。
所以你需要调用.toList()来完成查询执行。
由于数据量很大,您可以使用Select子句根据您的要求提取相对特定的列。
var todayStatus =
from s in actiContext.DeviceStatus
.Include(s1 => s1.Device.Panel.Select(d => new
{
d.DeviceId,
d.DeviceName,
d.PanelID
}))
where DbFunctions.TruncateTime(s.TimeStamp) == DbFunctions.TruncateTime( DateTimeOffset.Now)
&& s.Device.Panel.Mac == mac
&& (s.Device.Ty == 4 || s.Device.Ty == 9)
select s;
var tempList = todayStatus.toList();
答案 1 :(得分:0)
好的,这个请求是一种更简单的方法来实现这个目标:
using (var actiContext = new ActigraphyContext())
{
var todayLastStatus =
from s in actiContext.DeviceStatus.Include(s1 => s1.Device.Panel)
where DbFunctions.TruncateTime(s.TimeStamp) == DbFunctions.TruncateTime( DateTimeOffset.Now)
&& s.Device.Panel.Mac == mac
&& (s.Device.Ty == 4 || s.Device.Ty == 9)
orderby s.TimeStamp descending
select s;
var requestResult = todayLastStatus.Take(1).FirstOrDefault();
return requestResult;
}
但问题仍然存在:为什么我在第一次请求中没有获得相关对象?
答案 2 :(得分:-1)
在您执行类似ToList()的调用之前,查询实际上并未运行,这就是取消注释该行的原因。如果查询带回了太多数据,那么您需要更改查询以缩小您带回的数据量。