标签: eager-loading

急切地在 NHibernate 中加载 child 和 child-of-child 集合

NHibernate 试图加载一个小的数据层次结构时遇到了问题。我的域模型如下所示:

class GrandParent
{
    int ID{get;set;}
    IList<Parent> Parents {get; set;}
}

class Parent
{
    IList<Child> Children {get; set;}
}

class Child
{
}
Run Code Online (Sandbox Code Playgroud)

我想为给定的祖父母加载所有父母和孩子。这个 Linq-to-NH 查询创建了正确的 SQL 并按预期加载了 GrandParent:(该示例假设祖父母有 2 个父母,每个父母都有 2 个子对象 - 所以总共有 4 个子对象)。

var linq = session.Linq<GrandParent>();
linq.Expand("Parents");
linq.Expand("Parents.Children");
linq.QueryOptions.RegisterCustomAction(c => 
    c.SetResultTransformer(new DistinctRootEntityResultTransformer()));
var grandparent = (select g from session.Linq<GrandParent>()
                   where g.ID == 1
                   select g).ToList();

Assert(grandparent.Count == 1); //Works
Assert(grandparent.Parents.Count == 2); //Fails - count = 4!
Run Code Online (Sandbox Code Playgroud)

Grandparent.Parents 集合包含 4 个项目,其中 2 个是重复的。似乎 DistinctRootEntityResultTransformer …

c# nhibernate linq-to-nhibernate eager-loading

5
推荐指数
1
解决办法
2099
查看次数

Rails ActiveRecord 助手查找方法不急于加载关联

我有以下模型:Game 和 Pick。Game 和 Pick 之间存在一对多的关联。还有第三个模型叫做 Player,一个 Player 有很多 Picks。

Player 类中有一个方法可以为给定的游戏找到一个选择,或者如果它不存在则创建一个新的。

class Player < ActiveRecord::Base
  has_many :picks

  def pick_for_game(game)
    game_id = game.instance_of?(Game) ? game.id : game
    picks.find_or_initialize_by_game_id(game_id)
  end
end
Run Code Online (Sandbox Code Playgroud)

我想急切地为每个选择加载游戏。但是,如果我这样做

picks.find_or_initialize_by_game_id(game_id, :include => :game)
Run Code Online (Sandbox Code Playgroud)

它首先在此查询运行时获取选择(该方法运行多次),然后在访问每个选择时获取游戏。如果我将 default_scope 添加到 Pick 类

class Pick < ActiveRecord::Base
  belongs_to :game
  belongs_to :player
  default_scope :include => :game
end
Run Code Online (Sandbox Code Playgroud)

它仍然为每个选择生成 2 个选择语句,但现在它在选择后立即加载游戏,但它仍然没有像我期望的那样进行连接。

Pick Load (0.2ms)  SELECT "picks".* FROM "picks" WHERE "picks"."game_id" = 1 AND ("picks".player_id = 1) LIMIT 1
Game Load (0.4ms)  SELECT "games".* FROM "games" …
Run Code Online (Sandbox Code Playgroud)

activerecord ruby-on-rails eager-loading ruby-on-rails-3

5
推荐指数
1
解决办法
6018
查看次数

实体框架渴望加载过滤器

我有一个简单的查询,我想这样做:

1)ProductsChildProducts哪些有PriceTiers
2)我想得到所有Productsa Category的a ID为1和Display= true.
3)我想包含所有ChildProductsDisplay= true的东西.
4)然后包括PriceTiershas IsActive= true.

根据我的阅读,EF不支持使用过滤器进行预先加载,因此以下内容不起作用:

ProductRepository.Query.IncludeCollection(Function(x) x.ChildProducts.Where(Function(y) y.Display).Select(Function(z) z.PriceTiers.Where(Function(q) q.IsActive))).Where(Function(x) x.Categories.Any(Function(y) y.ID = ID)))
Run Code Online (Sandbox Code Playgroud)

有什么建议?

entity-framework eager-loading

5
推荐指数
1
解决办法
2676
查看次数

递归自加入急切加载?

我有一个自我加入的模型:

class Comment < ActiveRecord::Base
     belongs_to :parent, :class_name => 'Comment', :foreign_key => 'parent_id'
     has_many :children, :class_name => 'Comment', :foreign_key => "parent_id"
end
Run Code Online (Sandbox Code Playgroud)

后来我希望首先进行1次SQL调用以获取所有相关注释,然后递归渲染它们.

我如何递归加载?

comments = Comment.where(:post_id => @post_id).includes(:comments=> [:comments => [:comments .... #How do I get this to recursively eager load?

def show_comments(comment)
   render comment
   comment.children.each do |child|
       show_comments(child)
   end
end
Run Code Online (Sandbox Code Playgroud)

activerecord ruby-on-rails eager-loading

5
推荐指数
1
解决办法
856
查看次数

Doctrine2 预先加载运行多个查询而不是 1

我将 Symfony2 与 Doctrine2(最新版本)一起使用,并定义了这种关系:

/**
 * @ORM\OneToMany(targetEntity="Field", mappedBy="event", fetch="EAGER")
 * @ORM\OrderBy({"name" = "ASC"})
 */
protected $fields;
Run Code Online (Sandbox Code Playgroud)

关系的另一边定义为:

/**
 * @ORM\ManyToOne(targetEntity="Event", inversedBy="fields", fetch="EAGER")
 * @ORM\JoinColumn(nullable=false, onDelete="CASCADE")
 */
protected $event;
Run Code Online (Sandbox Code Playgroud)

在执行“fetchOnyById”时,Doctrine 运行 2 个查询。1 获取对象本身,1 获取相关字段。我希望这是一个连接,但它不是。

在控制器中完成后,我将对象传递给树枝。在那里我再次检索字段作为对象的属性。这会导致运行另一个查询以再次检索字段。

Clearly I'm doing something wrong, as I would expect only 1 query to be run and 3 are actually run.

eager-loading symfony doctrine-orm

5
推荐指数
1
解决办法
5726
查看次数

如何使用带有导轨的祖先宝石来急切加载根?

我有一个属于类别的条目模型。类别模型使用祖先,以便我可以嵌套类别。

我想按其根类别对所选条目进行分组。我遇到的问题是,为了做到这一点,rails 对每个条目执行查询以获取根类别。因此,如果我有 20 条记录,它将执行 20 个查询以按根类别分组。

我已经通过预先加载类别(如下所示)减少了查询数量,但我不知道如何预先加载类别的根。

这是我正在使用的代码:

控制器

@entries = current_user.entries.includes(:category)
@entries_by_category = @entries.group_by { |entry| entry.category.root }
Run Code Online (Sandbox Code Playgroud)

入口.rb

class Entry < ActiveRecord::Base
  belongs_to :category
end
Run Code Online (Sandbox Code Playgroud)

类别.rb

class Category < ActiveRecord::Base
  has_ancestry

  has_many :entries
end
Run Code Online (Sandbox Code Playgroud)

我试图把默认范围的分类模型,像这样:default_scope { includes(:ancestry) }。但这并没有改变执行查询的数量。而且我无法弄清楚如何includes()在原始查询上使用以包含类别和类别的根。

作为一些额外的信息,类别只能嵌套 2 层深(仅类别和子类别)。所以 root 在技术上意味着父级,它不必遍历多个级别。

有任何想法吗?

activerecord group-by ruby-on-rails eager-loading ancestry

5
推荐指数
1
解决办法
2025
查看次数

在实体上显式加载多个引用/集合

考虑以下实体模型:

public class Parent
{
    public virtual FirstChild FirstChild { get; set; }
    public virtual SecondChild SecondChild { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在我的代码中,我加载了Parent实体:

Parent parent = <loaded in some way>;
Run Code Online (Sandbox Code Playgroud)

要显式加载其导航属性,我使用

db.Entry(parent).Reference(p => p.FirstChild).Load();
db.Entry(parent).Reference(p => p.SecondChild).Load();
Run Code Online (Sandbox Code Playgroud)

但这会导致两个数据库查询。

问题:有没有更优雅的方式,允许在单个查询中显式加载多个导航属性?

如果我没有parent加载,我会立即加载:

Parent parent = db.Parents
    .Include(p => p.FirstChild)
    .Include(p => p.SecondChild)
    .FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

但是,正如我所提到的,我已经在没有相关实体的情况下加载了它(并且我无法修改加载代码)。

c# entity-framework eager-loading navigational-properties

5
推荐指数
1
解决办法
1737
查看次数

预先加载 ActiveRecord 中的自定义连接

我有一张有很多预订的餐馆的桌子。现在我想查询所有餐馆,如果他们有 2 人的预订,它应该预加载这些关联。如果没有 2 的预订,它仍应返回餐厅,但关联为空。

为此,我尝试了以下查询:

Restaurant.eager_load(:reservations).where("number_of_people = ?", 2)
Run Code Online (Sandbox Code Playgroud)

但是,这不起作用,因为它会丢弃所有有预订但都不是 2 人的餐厅。

所以我想做的是将该条件移动到连接条件中。就像是:

Restaurant.joins('LEFT OUTER JOIN \"reservations\" ON \"reservations\".\"restaurant_id\" = \"restaurants\".\"id\" AND \"reservations\".\"number_of_people\" = ?', 2)
Run Code Online (Sandbox Code Playgroud)

这将给出我需要的结果,但是这不是预加载“保留”关联而是导致 N+1 问题。

似乎eager_load 不接受自定义查询。我找到了这些线程:https : //github.com/rails/rails/issues/12270JOIN ON ... AND 在 ActiveRecord 中急切加载关联时的条件,但没有提供解决方案。

activerecord ruby-on-rails eager-loading

5
推荐指数
1
解决办法
2198
查看次数

laravel hydrateRaw/fromQuery 和带分页的预加载

我目前发现您可以对原始 sql 查询进行水合。

我有以下查询:

DB::table(DB::raw('(SELECT *, Y(location) AS longitude, X(location) AS latitude FROM meetings WHERE MBRCONTAINS(@quadrat, location)) AS sub'))
            ->select(DB::raw('(FLOOR(SQRT(POW((@ibk_breite - sub.latitude) * 111, 2) + POW((@ibk_laenge - sub.longitude) * 111 * ABS(COS(RADIANS(@ibk_breite))),2)))) AS distance, sub.*, latitude, longitude'));
Run Code Online (Sandbox Code Playgroud)

我按以下方式补水

$meetings = Meeting::fromQuery($query->toSql());
Run Code Online (Sandbox Code Playgroud)

在刀片视图中,我需要从不同的表中获取一些额外的数据,例如:

 $meeting->user
Run Code Online (Sandbox Code Playgroud)

其中引用了用户模型。但是,如果我不是完全错误的,那会在 for each 循环中导致 n+1 问题,因为我并不急于加载它?!那么是否可以像通常那样急切加载所需的模型

->with('user', 'books', 'etc...')
Run Code Online (Sandbox Code Playgroud)

??

也可以像$meetings = $query->paginate(5);这样对它进行分页 并做$meetings->withPath('home');

编辑:找到了一个解决方案:

// Do your query stuff
 // Get count before the query because it won't work with skip and …
Run Code Online (Sandbox Code Playgroud)

eager-loading laravel-pagination laravel-5.4

5
推荐指数
1
解决办法
2366
查看次数

laravel在创建父模型后急于使用with()vs load()进行加载

我正在创建一个Reply模型,然后尝试返回具有所有者关系的对象。这是返回空对象的代码:

//file: Thread.php
//this returns an empty object !!??
public function addReply($reply)
{
    $new_reply = $this->replies()->create($reply);
    return $new_reply->with('owner');
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我将with()方法换成load()方法以加载所有者关系,则可以得到预期的结果。那就是返回的回复对象及其相关的所有者关系:

//this works
{
    $new_reply = $this->replies()->create($reply);
    return $new_reply->load('owner');
}
Run Code Online (Sandbox Code Playgroud)

我不明白为什么。寻找澄清。

谢谢,耶

php eager-loading eloquent laravel-5 laravel-5.4

5
推荐指数
1
解决办法
1744
查看次数