ICollection上的AsQueryable()是否真的执行懒惰? [英] Does AsQueryable() on ICollection really makes lazy execution?

查看:95
本文介绍了ICollection上的AsQueryable()是否真的执行懒惰?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Entity Framework CodeFirst,其中使用了ICollection的父子关系作为

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

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

好的,到目前为止,一切都正常,但我的关注是,每当我想得到一个人的博客,我得到它作为

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

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



我知道我可以将博客声明为IQueryable我的上下文,以便我可以直接查询

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

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



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

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

对我来说看起来像一个魔术,似乎太好了,不能成真。所以我的问题这个AsQueryable是否真的使ICollection在现实中成为IQueryable,并使得SQL Server中的所有Query进程(Lazy加载)或者它只是一个转换,其中将博客加载到内存中,就像以前一样,但是将接口从ICollection更改为IQueryable? p>

解决方案

所以实际上看起来,将导航属性写成 IQueryable< T> 是不可能的



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

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

从中可以查询如下,因此它不会加载所有内容进入内存:

  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)

I am using Entity Framework CodeFirst where I have used Parent Child relations using ICollection as

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; }
}

Ok, so far everything is working ok, but my concern is, whenever I want to get the Blogs of a person, I get it as

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

Now, I understand that, when the line is executed, all Blogs for that person is loaded into the memory and then sorting and selecting is done from memory. That is not ideal for a record of Person who has large number of blogs. I want to make the Blog Child as IQueryable so that the Sorting and Selecting is done in SQL database before pulling to Memory.

I know I could declare the Blogs as IQueryable in my context so that I could directly query as

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

but that is not feasible for me due to design choice, I want to avoid any circular reference as much as possible due to serialization problem. So, I did not make any reference of the parent entity in my child.

I found that, i can call AsQueryable() method on the blogs as

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

That looks like a magic for me and seems too good to be true. So my question. Does this AsQueryable really make the ICollection as IQueryable in reality and makes all Query process in SQL Server (Lazy loading) OR it is just a casting where Blogs are loaded into memory as like before, but change the interface from ICollection to IQueryable ?

解决方案

So actually it appears that writing your navigation property as IQueryable<T> is not possible.

What you could do is adding a navigation property to 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; }
}

From that, you can query as follows so it won't load everything into memory:

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)

I suggest you to try LINQPad to see how LINQ is translated into SQL, and what is actually requested from the DB.

这篇关于ICollection上的AsQueryable()是否真的执行懒惰?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆