c# - ICollection 上的 AsQueryable() 真的可以延迟执行吗?

标签 c# entity-framework-4.1 ef-code-first iqueryable icollection

我正在使用 Entity Framework CodeFirst,其中我使用 ICollection 作为 Parent Child 关系

public class Person
{
   public string UserName { get;set}
   public ICollection<Blog> Blogs { get; set;}
}

public class Blog
{
   public int id { get; set; }
   public string Subject { get; set; }
   public string Body { get; set; }
}

好的,到目前为止一切正常,但我担心的是,每当我想获取某人的博客时,我都会将其作为

var thePerson = _context.Persons.Where(x => x.UserName = 'xxx').SingleOrDefault();
var theBlogs = thePerson.Blogs.OrderBy(id).Take(5);

现在,我明白了,当该行被执行时,那个人的所有博客都被加载到内存中,然后从内存中完成排序和选择。这对于拥有大量博客的 Person 的记录来说并不理想。我想将 Blog Child 设为 IQueryable,以便在拉入内存之前在 SQL 数据库中完成排序和选择。

我知道我可以在我的上下文中将博客声明为 IQueryable,这样我就可以直接查询为

var theBlogs = _context.Blogs.Where(.....)

但由于设计选择,这对我来说是不可行的,由于序列化问题,我想尽可能避免任何循环引用。因此,我没有在我的 child 中提及父实体。

我发现,我可以在博客上调用 AsQueryable() 方法

var theBlogs = thePerson.Blogs.AsQueryable().OrderBy(id).Take(5);

这对我来说就像一个魔法,好得令人难以置信。所以我的问题。这个 AsQueryable 是否真的使 ICollection 实际上成为 IQueryable 并使 SQL Server 中的所有查询过程(延迟加载)或者它只是像以前一样将博客加载到内存中的转换,但将接口(interface)从 ICollection 更改为 IQueryable ?

最佳答案

所以实际上看起来将您的导航属性写为 IQueryable<T> is not possible .

您可以做的是将导航属性添加到 Blog :

public class Blog
{
   public int id { get; set; }
   public string Subject { get; set; }
   public string Body { get; set; }
   public virtual Person Owner { get; set; }
}

由此,您可以按如下方式查询,这样它就不会将所有内容都加载到内存中:

var thePerson = _context.Persons.Where(x => x.UserName = 'xxx').SingleOrDefault();
var results = _context.Blogs.Where(z => z.Person.Name = thePerson.Name).OrderBy(id).Take(5)

我建议你试试LINQPad查看 LINQ 如何转换为 SQL,以及从数据库实际请求的内容。

关于c# - ICollection 上的 AsQueryable() 真的可以延迟执行吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9191094/

相关文章:

c# - 在实体中正确创建导航类

c# - 向用户发送消息时的 PEER_ID_INVALID

c# - 如何使用 protobuf 将 ServiceStack 服务与非 ServiceStack 客户端集成?

sql-server-2008 - SQL Server 2008 FILESTREAM 进度指示器

entity-framework - EF CF 手动配置多对多映射

c# - 乐观并发 : IsConcurrencyToken and RowVersion

c# - asp.net 中的 Paypal 快速结帐

c# - EF 失败将 View 映射到对象

c# - 使用原始 SQL 预加载实体

entity-framework - EF6 Code First - 使用不匹配的外键配置一对一关系