[英]Proper Implementation of IQueryable as a Member Variable on a Model?
我是.Net,ASP,Entity Framework和Linq的新手,所以请忍受...
我最初建立的模型如下:
public class Pad
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid PadId { get; set; }
public string StreetAddress { get; set; }
public int ZipCode { get; set; }
public virtual ICollection<Mate> Mates { get; set; }
public virtual ICollection<Message> Messages { get; set; }
}
(一个便笺簿是一个聊天室-它包含许多伙伴和成千上万条消息)在Web API控制器中,我具有一个旨在从指定的便笺簿中获取25条最新消息的函数。
public IHttpActionResult GetMessages(string id)
{
var padGuid = new Guid(id);
// Try to find the pad referenced by the passed ID
var pads = (from p in db.Pads
where p.PadId == padGuid
select p);
if (pads.Count() <= 0)
{
return NotFound();
}
var pad = pads.First();
// Grab the last 25 messages in this pad.
// PERFORMANCE PROBLEM
var messages = pad.Messages.OrderBy(c => c.SendTime).Skip(Math.Max(0, pad.Messages.Count() - 25));
var messagesmodel = from m in messages
select m.toViewModel();
return Ok(messagesmodel);
}
此实现的问题在于,在获得计数,排序等之前, EF似乎正在将整个消息集(成千上万条)加载到内存中 。这导致Pads中的大量性能下降,并带有大量消息。
我的第一个想法是将Pad.Messages
成员类型转换为IQueryable
而不是ICollection
这应该将Linq查询推迟到SQL,或者我想。 但是,执行此操作后,上面的pad.Messages.Count()
类的函数会抱怨-原来pad.Messages
是一个空值! 并且它在其他地方中断,例如将新的Messages
添加到Pad.Messages
值。
这样的东西的正确实现是什么? 在其他地方,我已经看到推荐的解决方案是针对上下文(如select Messages where PadId = n
)构造第二个查询,但是当我可以使用Messages成员值时,这似乎并不直观。
谢谢!
var messages = db.Pads.Where(p => p.PadId == padGuid)
.SelectMany(pad => p.Messages.OrderBy(c => c.SendTime)
.Skip(Math.Max(0, pad.Messages.Count() - 25)));
您如何计划在不实际执行数据库查询的情况下计算数据库查询中的结果数?
您打算如何在不实际执行查询的情况下获取查询中的第一项?
你不能做任何事。 两者都必须执行查询。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.