EF学习杂技37:如何实现Conditional Include
2010-09-01 16:04
190 查看
问题描述 有些朋友希望使用这样的一种查询方式,比如要查询Movies实体对象,同时想通过预先加载方式加载相关的Reviews对象,但是又希望只加载符合条件的部分Reviews。
很不幸的是,EF并不能满足这样的功能ObjectQuery<Movie>.Include(…)方法只能加载全部或者全部不加载。
解决方案
下面的变通方法可以实现上面的要求: public class Movie
{
public int ID {get;set;}
public string Name {get;set;}
public string Genre {get;set;}
public List<Review> Reviews {get;set;}
}
public class Review
{
public int ID {get;set;}
public int Stars {get;set;}
public string Summary {get;set;}
public Movie Movie {get;set;}
public User User {get;set;}
}
假设你想要获取影片“Horror”所述的带有5颗星的Reviews,你可以像下面这样:
var dbquery =
from movie in ctx.Movies
where movie.Genre == “Horror”
select new {
movie,
reviews = from review in movie.Reviews
where review.Stars == 5
select review
};
var movies = dbquery
.AsEnumerable()
.Select(m => m.movie);
现在来看一下上面的代码为什么能够成功执行?
首先第一个查询就创建了一个包含所有Horror影片及其包含5颗星的Reviews的新的实例。
第二个查询利用LINQ to Object的AsEnumerable()方法进行了一次内存查询,简单的采用非拆包方式从匿名类型中得到了相关的实例,内每个Movie中将包含了经过过滤的Reviews。
所以下面的代码断言都将通过,
foreach(var movie in movies)
{
foreach(var review in movie.Reviews)
Assert(review.Rating == 5);
}
上面的代码能够实现的原因是因为EF引入了一种叫做relationship fix-up的机制。
relationship fix-up假设所有相关的对象将在第二种实体对象进入到ObectContext的时候被自动挂接,这里我们在讲对象装载入ObjectContext的时候只包含了相应的Movie和经过过滤的相关的Reviews,EF就默认为他们已经自动挂接了,那意味着那些被过滤的Reviews将自动填充Movie的Review数组。
简而言之,这种Relationship fix-up方式(我这里叫他Relationship改进)将可以应用到你的高级应用中。
很不幸的是,EF并不能满足这样的功能ObjectQuery<Movie>.Include(…)方法只能加载全部或者全部不加载。
解决方案
下面的变通方法可以实现上面的要求: public class Movie
{
public int ID {get;set;}
public string Name {get;set;}
public string Genre {get;set;}
public List<Review> Reviews {get;set;}
}
public class Review
{
public int ID {get;set;}
public int Stars {get;set;}
public string Summary {get;set;}
public Movie Movie {get;set;}
public User User {get;set;}
}
假设你想要获取影片“Horror”所述的带有5颗星的Reviews,你可以像下面这样:
var dbquery =
from movie in ctx.Movies
where movie.Genre == “Horror”
select new {
movie,
reviews = from review in movie.Reviews
where review.Stars == 5
select review
};
var movies = dbquery
.AsEnumerable()
.Select(m => m.movie);
现在来看一下上面的代码为什么能够成功执行?
首先第一个查询就创建了一个包含所有Horror影片及其包含5颗星的Reviews的新的实例。
第二个查询利用LINQ to Object的AsEnumerable()方法进行了一次内存查询,简单的采用非拆包方式从匿名类型中得到了相关的实例,内每个Movie中将包含了经过过滤的Reviews。
所以下面的代码断言都将通过,
foreach(var movie in movies)
{
foreach(var review in movie.Reviews)
Assert(review.Rating == 5);
}
上面的代码能够实现的原因是因为EF引入了一种叫做relationship fix-up的机制。
relationship fix-up假设所有相关的对象将在第二种实体对象进入到ObectContext的时候被自动挂接,这里我们在讲对象装载入ObjectContext的时候只包含了相应的Movie和经过过滤的相关的Reviews,EF就默认为他们已经自动挂接了,那意味着那些被过滤的Reviews将自动填充Movie的Review数组。
简而言之,这种Relationship fix-up方式(我这里叫他Relationship改进)将可以应用到你的高级应用中。
相关文章推荐
- EF学习笔记28:如何实现自己的预先加载(Eager Loading)策略
- EF学习杂记27:如何实现BeforeSave Validation
- Entity Framework 学习中级篇—EF支持复杂类型的实现
- Android 框架学习2:源码分析 EventBus 3.0 如何实现事件总线
- 干货 | 如何使用 CNN 推理机在 IoT 设备上实现深度学习
- django学习——用户注册时如何实现验证码图片
- Qt+openGL学习记录(4)`如何实现物体在三维坐标系中的旋转`
- Menu学习,和如何实现一步关闭所有的activity退出应用程序
- Android 学习笔记之SurfaceView的使用+如何实现视频播放...
- 如何使用CNN推理机在IoT设备上实现深度学习
- django学习——如何实现简单的搜索功能
- Linux学习-->如何通过Shell脚本实现发送邮件通知功能?
- 黑马程序员之ORACLE数据库学习笔记:如何实现连接池及连接池的优缺点
- 【CSS/JS学习】如何实现单行/多行文本溢出的省略(...)--老司机绕过坑道的正确姿势
- Community Server 2.0 学习笔记:如何实现在线人数?
- .Net语言 APP开发平台——Smobiler学习日志:如何快速实现地图定位时的地点微调功能
- Block学习-关于Block是如何实现的,以及block中参数传递
- .Net语言 APP开发平台——Smobiler学习日志:如何实现微信朋友圈的消息样式?
- CQRS学习——Storage实现(EF+Code First+DynamicReponsitory)[其四]