实体框架:过滤导航属性 [英] Entity Framework: Filtering Navigation Properties

查看:117
本文介绍了实体框架:过滤导航属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正与实体框架 - code首先,我有下一个上下文(提取至少):

 公共类的TestContext:的DbContext
{
    公共DbSet<使用者>用户{获得;组}
    公共DbSet<图书>图书{获得;组}
}
 

和用户的类我有这样的导航属性:

  public虚拟集合<图书>图书{获得;组}
 

ERGO,用户有很多书。 问题是,我要过滤的书,但因为我有像500.000的书在我的数据库,我买不起把所有的书,记忆和后过滤。我需要执行对与过滤一句数据库查询。

当我这样做:

  //不要紧,我如何获得用户...
VAR allBooks = user.Books; //这带给用户的所有的书
VAR activeBooks = allBooks.Where(N => n.Active);
 

我觉得你可以看到这个问题......我想在执行前将过滤器添加到查询...但我不知道我怎么能做到这一点。

我会AP preciate任何意见了。

感谢。

编辑:

与明确的情况下另外一个例子,可能是清楚的事情了......

 的IQueryable<课程> 。查询=新的TestContext()设置<使用者>(); //它不运行查询呢。
VAR一个= query.Where(N => n.Active); //这运行的查询!
变种B = a.ToList(); //该项目是在记忆...
 

解决方案

我个人没有看到你在做什么任何问题。图书列表将不会被加载到内存中,直到您的GetEnumerator(),显式或通过调用的foreach等。

  VAR activeBooks = user.Books.Where(N => n.Active); //仍然IQueryable的
变种inMemory = activeBooks.ToList(); //执行的IQueryable
//要么
的foreach(在activeBooks VAR书)
    {

    }
 

修改

您可能需要阅读上的IQueryable的 http://msdn.microsoft.com/en-us/library/system.linq.iqueryable(V = vs.110)的.aspx

  

的IQueryable的接口继承IEnumerable接口,以便如果它重新presents的查询,该查询的结果可被列举。枚举导致执行用一个IQueryable对象相关联的前pression树。的执行一个前pression树的定义是特定于一个查询提供者。例如,它可能涉及翻译前pression树到一个适当的查询语言基础数据源。查询不返回枚举的结果执行时,执行方法被调用。

这意味着,为了执行必须枚举可枚举该查询。

 的IQueryable<课程> 。查询=新的TestContext()设置<使用者>(); //它不运行查询呢。

IQueryable的<课程> A = query.Where(N => n.Active); //还没有执行

IQueryable的<课程> C = a.Where(N => n.Title.Contains(科学)); //还是不执行

名单<课程> B = a.ToList(); //执行查询
 

I am working with Entity Framework - Code First, and i have the next context (an extraction at least):

public class TestContext : DbContext
{
    public DbSet<User> Users { get; set}
    public DbSet<Book> Books { get; set}
}

And in the user's class i have this navigation property:

public virtual Collection<Book> Books { get; set}

ergo, a user has many books. The problem is that i want to filter the books, but as i have like 500.000 books on my database, i can't afford bringing all the books to memory and filter them later. I need to execute the query against the database with the filter sentence.

When i do this:

// Doesn't matter how i get the user...
var allBooks = user.Books; // Here it brings all the books of the user
var activeBooks = allBooks.Where(n => n.Active);

I think you can see the problem... i want to add filters to the query before executing it... but i don't know how can i do that.

I would appreciate any advice too.

Thanks.

EDIT:

Another example with the explicit context, may be it clear things up...

IQueryable<Course> query = new TestContext().Set<User>(); // It doesn't run the query yet.
var a = query.Where(n => n.Active); // Here it runs the query!
var b = a.ToList(); // The items was on memory...

解决方案

I personally don't see any problem with what you are doing. The list of books will not be loaded into memory until you GetEnumerator(), either explicitly or by invoking foreach etc..

var activeBooks = user.Books.Where(n => n.Active); //still iqueryable
var inMemory = activeBooks.ToList(); //executes iqueryable
//or
foreach(var book in activeBooks)
    {

    } 

Edit

you may want to read up on IQueryable http://msdn.microsoft.com/en-us/library/system.linq.iqueryable(v=vs.110).aspx

"The IQueryable interface inherits the IEnumerable interface so that if it represents a query, the results of that query can be enumerated. Enumeration causes the expression tree associated with an IQueryable object to be executed. The definition of "executing an expression tree" is specific to a query provider. For example, it may involve translating the expression tree to an appropriate query language for the underlying data source. Queries that do not return enumerable results are executed when the Execute method is called."

This means that in order to execute the query you must enumerate the enumerable.

IQueryable<Course> query = new TestContext().Set<User>(); // It doesn't run the query yet.

IQueryable<Course> a = query.Where(n => n.Active); // Not executed yet

IQueryable<Course> c = a.Where(n => n.Title.Contains("Science")); //still not executed

List<Course> b = a.ToList(); //Executes the query

这篇关于实体框架:过滤导航属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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