如何在nhibernate queryover中选择引用的实体

Joã*_*oni 11 nhibernate select lazy-loading eager-loading queryover

我有一个具有引用其他实体的属性的实体(示例中为ReferenceEntity).

使用HQL,我可以这样做:

select e.ReferenceEntity from Entity e where e.Id = :entityId
Run Code Online (Sandbox Code Playgroud)

NHibernate会给我一个没有懒惰的ReferenceEntity实例.

通过im尝试查询执行此操作:

Session.QueryOver<Entity>()
.Where(e => e.Id == entityId)
.Select(e => e.ReferenceEntity)
.SingleOrDefault<ReferenceEntity>()
Run Code Online (Sandbox Code Playgroud)

使用QueryOver Nhibernate给了我ReferenceEntity但是懒惰.

我想通过查询来获得ReferenceEntity和eager加载,就像我使用hql一样.

谢谢

Dan*_*ing 11

建议#1

在执行查询以获取所需数据后,可以执行一些LINQ操作.

var result = Session.QueryOver<Entity>()
    .Where(e => e.Id == entityId)        // Filter,
    .Fetch(e => e.ReferenceEntity).Eager // join the desired data into the query,
    .List()                              // execute database query,
    .Select(e => e.ReferenceEntity)      // then grab the desired data in-memory with LINQ.
    .SingleOrDefault();
Console.WriteLine("Name = " + result.Name);
Run Code Online (Sandbox Code Playgroud)

它很简单,完成工作.

在我的测试中,它导致了一个查询.这是输出:

SELECT
    this_.Id as Id0_1_, this_.Name as Name0_1_, this_.ReferenceEntity_id as Referenc3_0_1_,
    q5379349_r2_.Id as Id1_0_, q5379349_r2_.Name as Name1_0_
FROM
    [Entity] this_
    left outer join [ReferenceEntity] q5379349_r2_
        on this_.ReferenceEntity_id=q5379349_r2_.Id
WHERE this_.Id = @p0;
Run Code Online (Sandbox Code Playgroud)

建议#2

另一种方法是使用EXISTS子查询,它稍微复杂一些,但是第一次返回正确的结果而不需要后数据库操作:

ReferenceEntity alias = null;
var result = Session.QueryOver(() => alias)
    .WithSubquery.WhereExists(QueryOver.Of<Entity>()
        .Where(e => e.Id == entityId)                 // Filtered,
        .Where(e => e.ReferenceEntity.Id == alias.Id) // correlated,
        .Select(e => e.Id))                           // and projected (EXISTS requires a projection).
    .SingleOrDefault();
Console.WriteLine("Name = " + result.Name);
Run Code Online (Sandbox Code Playgroud)

经过测试 - 单个查询结果:

SELECT this_.Id as Id1_0_, this_.Name as Name1_0_
FROM [ReferenceEntity] this_
WHERE exists (
    SELECT this_0_.Id as y0_
    FROM [Entity] this_0_
    WHERE this_0_.Id = @p0 and this_0_.ReferenceEntity_id = this_.Id);
Run Code Online (Sandbox Code Playgroud)