我有一个具有引用其他实体的属性的实体(示例中为ReferenceEntity)。
使用HQL我可以这样做:
select e.ReferenceEntity from Entity e where e.Id = :entityId
NHibernate会给我一个没有懒惰的ReferenceEntity实例。
查询即时尝试执行此操作:
Session.QueryOver<Entity>()
.Where(e => e.Id == entityId)
.Select(e => e.ReferenceEntity)
.SingleOrDefault<ReferenceEntity>()
使用QueryOver Nhibernate给了我ReferenceEntity但是懒惰。
我想使用查询来获得ReferenceEntity和eager加载,就像我使用hql一样。
谢谢
建议#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);
它很简单,可以完成工作。
在我的测试中,它产生了一个查询。这是输出:
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;
建议#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);
经过测试 - 单个查询结果:
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);
建议#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);
它很简单,可以完成工作。
在我的测试中,它产生了一个查询。这是输出:
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;
建议#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);
经过测试 - 单个查询结果:
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);
如果我理解你,这就是你需要的:
Session.QueryOver<Entity>()
.Where(e => e.Id == entityId)
//!!!
.Fetch(e=>e.ReferenceEntity).Eager
.Select(e => e.ReferenceEntity)
.SingleOrDefault<ReferenceEntity>()
尝试这个:
Session.QueryOver<Entity>()
.Where(e => e.Id == entityId)
.Fetch(e=>e.ReferenceEntity).Eager
.Select(e => e.ReferenceEntity)
.TransformUsing(Transformers.AliasToBean<ReferenceEntity>())
.SingleOrDefault<ReferenceEntity>()