首先,请不要试图争论我做出的热切负载 - 遍历对象图并导致(通过延迟加载)甚至超过一次往返数据库只是不是一种选择.
我有一个大的对象图.我想获取根对象,以及它的子,孙子,曾孙等的子集.目前我通过创建多个Future对象(使用Criteria)来执行此操作,并且在每个对象中,我这样做SetFetchMode("...", FetchMode.Eager)- 请参阅Ayende的帖子和Sam的第3条评论在这里.有两个问题:
NHibernate在同一个往返中执行多个选择查询 - 从根到叶子(A.B.C.D)的每个路径一个,这很好,但使用join而不是subselect我真正想要它做的事情.使用join意味着需要从数据库发送大量数据,需要进行解析,并且nhibernate需要做更多的工作而不是必要的.
问题1的结果 - 在某些情况下,对象的重复嵌套多于一层.
第二个问题我通过将我的集合设置为Set来"解决",但后来我失去了排序能力 - 因为我必须指定ISet为接口,我的代码无法知道该集合是否真的是一个OrderedSet.
有没有人知道如何执行,在一次往返,急切加载一个对象加上几个深层嵌套的集合,但不使用连接?
我非常感激!我已经在网上搜索了答案,显然我不是第一个打到这堵墙的人.
我正在使用Entity Framework 4.1代码的第一种方法.
我希望将eager加载作为我的dafault配置,并避免在每个提取查询中使用Include扩展方法.
我在MSDN中建议,在DbContext构造函数中更改简单的lazy属性:
public class EMarketContext : DbContext
{
public EMarketContext()
{
// Change the default lazy loading to eager loading
this.Configuration.LazyLoadingEnabled = false;
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这种方法不起作用.我必须使用Include方法在每个查询中执行预先加载.有什么想法吗?提前致谢.
在热切加载的文档中,声明:
如果您急切地使用指定的:limit选项加载关联,它将被忽略,返回所有关联的对象:
class Picture < ActiveRecord::Base
has_many :most_recent_comments, :class_name => 'Comment',
:order => 'id DESC', :limit => 10
end
Run Code Online (Sandbox Code Playgroud)
Picture.find(:first,:include =>:most_recent_comments).most_recent_comments#=>返回所有相关注释.
如果是这种情况,那么实现加载"限制"的最佳方法是什么?
假设我们急切地将最近10篇博客帖子加载到博客的首页上,我们显然不希望它们都是如此,那么是否应该指定帖子集合的限制和排序?
除此之外,可以在深度加载的元素上指定相同的条件 - 例如,仅在每篇博客文章中显示前三个评论吗?
Blog.find(:blog_id, :include => {:posts => :comments } )
Run Code Online (Sandbox Code Playgroud) 塔克类:
[Key]
public int TaakId { get; set; }
public int Pid { get; private set; }
[Required]
[Range(0,23.5)]
public double Uur { get; private set; }
[Required]
public Functie Functie { get; private set; }
public List<Taak> Taken { get; private set; }
[NotMapped]
public ICollection<WerknemerTaak> Werknemers { get; set; }
Run Code Online (Sandbox Code Playgroud)
WerknemerTaak 类:
[Required]
public Werknemer Werknemer { get; set; }
[Required]
public Taak Taak { get; set; }
public Afdelingen Afdeling { get; set; }
public string Taakbeschrijving …Run Code Online (Sandbox Code Playgroud) 在EF eager中,加载相关实体很容易.
但是在使用table-per-type模型加载数据时,我遇到了包括继承实体在内的困难.
这是我的模特:
实体:
ArticleBase (基础文章实体)
ArticleSpecial(继承自ArticleBase)UserBase (基本用户实体)
UserSpecial(继承自UserBase)Image关系如图所示(省略许多列): alt text http://i48.tinypic.com/5x4kdc.jpg
实际上,我的用户总是类型UserSpecial,因为UserBase在另一个应用程序中使用,因此我们可以共享凭据.这是我有两个单独的表的唯一原因.UserBase表格不能以任何形式或形式进行更改,因为其他应用程序会破坏.
我怎么想加载ArticleSpecial既CreatedBy和EditedBy设置,使两者都是类型UserSpecial(定义Image关系)?
我尝试过这些选项(虽然不成功):
1. 使用lambda表达式:
context.ArticleBases
.OfType<ArticleSpecial>()
.Include("UserCreated.Image")
.Include("UserEdited.Image");
Run Code Online (Sandbox Code Playgroud)
在这种情况下,问题是,无论是CreatedBy和EditedBy相关的UserBase,没有定义Image导航.所以我应该以某种方式将这两个UserSpecial类型转换为:
context.ArticleBases
.OfType<ArticleSpecial>()
.Include("UserCreated<UserSpecial>.Image")
.Include("UserEdited<UserSpecial>.Image");
Run Code Online (Sandbox Code Playgroud)
但当然使用泛型Include("UserCreated<UserSpecial>.Image")不起作用.
2. 我尝试过使用LINQ查询
var results = from articleSpecial in …Run Code Online (Sandbox Code Playgroud) 我正在使用带有MVC的Entity Framework 4,并且需要确保在我的视图中使用的任何引用实体在控制器方法返回之前已经加载,否则视图会吐出可怕的:
ObjectContext实例已被释放,不能再用于需要连接的操作.
直接从上下文中选择时,我可以使用该Include(string)方法强制它们包含在生成的SQL查询中:
var sellers = context.Sellers.Include("Recommendations.User").ToList();
Run Code Online (Sandbox Code Playgroud)
但是,如果我(例如)一个接受实体并需要加载所有项目的辅助方法,则没有Include可用的方法.
void Test(Seller seller)
{
// ensure all recommendations and their users are loaded
}
Run Code Online (Sandbox Code Playgroud)
蛮力方法是循环它们:
foreach (var recommendation in seller.Recommendations)
recommendation.User.ToString(); // just force a load
Run Code Online (Sandbox Code Playgroud)
如果我有100条建议,这将在幕后创建101个SQL查询.理想情况下,我想要一个方法/方法,只需一次SQL访问即可加载所有RecommendationAND User对象.
给我看看钱款.
编辑我真的不想讨论这是一个好的或坏的架构.为了这个问题,我简化了我的方案.你能用EF API做我想问的吗?
编辑2
拉迪斯拉夫的编辑提供了一种新方法的希望,但似乎我并不存在.
我可以通过这个实现我想要的东西:
context.Sellers.Include("Recommendations.User").Single(s => s.Id == seller.Id);
Run Code Online (Sandbox Code Playgroud)
这种方法不适用于LoadProperty......
context.LoadProperty(seller, "Recommendations.User");
Run Code Online (Sandbox Code Playgroud)
......因为错误而失败了......
找不到指定的导航属性Recommendations.User.
如果您没有对上下文的引用,这些方法都不起作用.
在RoR中,新人加载类和这样的分区是很常见的错误#解决方案是急切负载
# The bellow generates an insane amount of queries
# post has many comments
# If you have 10 posts with 5 comments each
# this will run 11 queries
posts = Post.find(:all)
posts.each do |post|
post.comments
end
Run Code Online (Sandbox Code Playgroud)
渴望加载的解决方案非常简单
# should be 2 queries
# no matter how many posts you have
posts = Post.find(:all, :include => :comments) # runs a query to get all the comments for all the posts
posts.each do |post|
post.comments # runs a query …Run Code Online (Sandbox Code Playgroud) 我正在努力获取所有相关元素的数据.我使用Laravel作为REST后端服务,将Json暴露给前端javascript应用程序.
考虑我有以下表格:
+----------------+ +----------------+ +-------------+
|topics | |posts | |users |
+----------------+ +----------------+ +-------------+
|id: int | |id: int | |id: int |
|title: varchar | |content: varchar| |name: varchar|
|content: varchar| |user_id: int | +-------------+
|user_id: int | |topic_id: int |
+----------------+ +----------------+
Run Code Online (Sandbox Code Playgroud)
一个主题有0到多个帖子,它有一个作者(用户)
帖子有一位作者(用户)
UML:http://i58.servimg.com/u/f58/11/26/57/95/intrep10.png
class User extends Eloquent {
protected $table = 'users';
public function topics() {
reutrn $this->hasMany('Topic');
}
public function posts() {
reutrn $this->hasMany('Post');
}
}
class Topic extends …Run Code Online (Sandbox Code Playgroud) 在我看来,片段缓存和急切加载 - 至少有时 - 在某种程度上相互矛盾.假设我有一个用户,他有很多帖子,每个帖子都有很多评论,反过来也可以有很多评论等等.
当我必须渲染页面时,我可以选择热切地加载用户,所有帖子,所有评论等等,以避免数据库n-1次.或者我可以懒惰地加载每个对象并依赖片段缓存来仅查询数据库中的新对象或已更改的对象.使用片段缓存和急切加载似乎都是浪费,因为我可能会做一个非常复杂的查询并实例化很多对象只是为了使用它们中的一小部分.
但是,如果我有一个应用程序,其中一个用户有许多Foos,而这些Foos又有很多Bars等等,但是其中每个Foo都是同时创建完整的所有Bars及其相关对象,从那时起就永远不会改变.在这种情况下,我想对已经渲染的Foos使用片段缓存,但是当我必须加载一个带有所有相关对象的新Foo时,要使用预先加载.毕竟,在更细粒度的级别缓存片段没有任何好处.
Rails实现这一目标的最佳方式是什么?我想我可以做一个查询来获取Foo的id,然后在我必须渲染每个Foo时用急切加载进行显式查找.这样做有更好/更优雅/更惯用的方式吗?
performance caching ruby-on-rails fragment-caching eager-loading
我有一个简单的问题,但似乎找不到解决方法.我正在使用Entity Framework Core版本2.0.1,并且希望默认情况下急切加载我的所有实体.
例:
public class Order
{
public int Id { get; set; }
public string Name { get; set; }
public int CustomerId { get; set; }
public Customer Customer { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public int AddressId { get; set; }
public Address Address { get; set; }
}
public class Address
{
public int Id { get; set; …Run Code Online (Sandbox Code Playgroud) eager-loading ×10
.net ×2
activerecord ×2
c# ×2
caching ×1
eloquent ×1
inheritance ×1
join ×1
laravel ×1
lazy-loading ×1
nhibernate ×1
optimization ×1
performance ×1
php ×1
subquery ×1