gpt4 book ai didi

nhibernate - NHibernate 可以在不延迟加载整个集合的情况下查询特定的子项吗?

转载 作者:行者123 更新时间:2023-12-04 01:09:43 29 4
gpt4 key购买 nike

当我有一个带有一对多子集合的实体对象时,我需要查询一个特定的子对象,是否有我还没有想出的功能或一些巧妙的模式来避免 NHibernate获取整个子集合?

例子:

class Parent 
{
public virtual int Id { get; proteced set; } // generated PK
public virtual IEnumerable<Child> Children { get; proteced set; }
}

class Child
{
public virtual int Id { get; protected set; } // generated PK
public virtual string Name { get; protected set; }
public virtual Parent Parent { get; protected set; }
}

// mapped with Fluent

class Service
{

private readonly ISessionFactory sessionFactory;

public Service(ISessionFactory sessionFactory)
{
this.sessionFactory = sessionFactory;
}

void DoSomethingWithChildrenNamedBob(int parentId)
{
using(var session = sessionFactory.OpenSession())
{
var parent = session.Get<Parent>(parentId);
// Will cause lazy fetch of all children!
var childrenNamedBob = parent.Children.Where(c => c.Name == "Bob");
// do something with the children
}
}
}

我知道这不是最好的例子,因为在这种情况下,可能只是直接查询子实体,但我遇到过这样的情况,我已经有一个父对象,需要通过它遍历特定​​的子树。

最佳答案

简短的回答:没有。更长的答案:您可以通过一些技巧让它做到这一点。

Rippo 上面的回答显示了你将如何以“正确的”NHibernate 方式进行操作(无论是使用 Linq 还是 QueryOver 或 HQL 并不重要 - 关键是你必须走出父 ->子关系来做一个询问)。您可以更进一步,将其伪装在外观后面。但要做到这一点,您必须完全删除映射关系,并始终将其替换为查询。您将删除 Parent -> Children 映射,但保留 Child -> Parent 映射不变;然后重写 Parent 上的属性,如下所示:

public virtual IQueryable<Child> Children
{
get
{
// somehow get a reference to the ISession (I use ambient context), then
return session.Query<Child>().Where(c => c.Parent == this);
}
}

现在,当您使用 Parent.Children 时,您会得到一个可查询的集合,这样您就可以编写

IEnumerable<Child> childrenNamedBob = parent.Children.Where(c => c.Name == "Bob");

您可以执行此操作并保留映射的唯一方法是修改 NHibernate 的集合对象(或注入(inject)您自己的对象)。 Diego Mijelshon(负责这些部分)写了一个尖峰,将 IQueryable 支持添加到 NHibernate 集合中,这样你就可以做

IEnumerable<Child> childrenNamedBob = parent.Children.AsQueryable().Where(c => c.Name == "Bob");

但据我所知,这从未有任何进展,也没有明显的计划将此功能添加到 NH。我已经运行了 Diego 的代码并且它确实有效,但显然它不是生产质量并且没有经过测试,而且我认为它从未被正式“发布”,即使是作为私有(private)补丁也是如此。

这是 NH 问题跟踪器上讨论的链接:https://nhibernate.jira.com/browse/NH-2319

我相信 NH 应该开箱即用地支持这一点,因为对于大多数 .NET 开发人员来说,这是一种自然的方式,他们希望与几乎所有可枚举的东西进行交互,现在我们有了 Linq,而且没有侧面就无法做到这一点- 将无界集合加载到 RAM 中的效果很糟糕。但传统的 NH 模型是 session -> 查询,这就是 99% 的人使用的。

关于nhibernate - NHibernate 可以在不延迟加载整个集合的情况下查询特定的子项吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14334618/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com