【发布时间】:2023-03-05 13:58:01
【问题描述】:
我有这个对象图:
// Lots of stuff omitted for brevity; these are all virtual properties and there
// are other properties which aren't shown on all classes.
class A {
B b;
C c;
DateTime timestamp;
}
class B {
X x;
Y y;
}
class X {
int id;
}
class C { }
class Y { }
or to put it more simply,
a = {
b: {
x { id: int },
y: { }
},
c: { },
timestamp: DateTime
}
现在我正在查询我将返回As 的列表,我需要他们所有的Bs、Cs、Xs 和Ys。我还将按 B 将它们分组到查找中。
ILookup<B, A> GetData(List<int> ids) {
using (ISession session = OpenSession()) {
var query = from a in session.Query<A>()
where ids.Contains(a.b.x.id)
orderby A.timestamp descending
select a;
query = query
.Fetch(a => a.b)
.ThenFetch(b => b.x)
.Fetch(a => a.b)
.ThenFetch(b => b.y)
.Fetch(a => a.c);
return query.ToLookup(a => a.b);
}
}
需要注意的几点:
- 这是一个需要返回所有数据的报告 - 无限的结果不是问题。
- 我正在使用
ToLookup进行分组,因为当您需要所有实际值时,使用group by似乎更复杂——您需要查询数据库中的组,然后查询它们的实际值。
我的问题是如何正确指定获取策略。我这样做的方式是我发现它运行的唯一方式(已获取所有 b.x 和 b.y 值) - 但它产生的 SQL 似乎是错误的:
select /* snipped - every mapped field from a0, b1, x2, b3, y4, c5 - but not b6 */
from [A] a0
left outer join [B] b1
on a0.B_id = b1.BId
left outer join [X] x2
on b1.X_id = x2.XId
left outer join [B] b3
on a0.B_id = b3.BId
left outer join [Y] y4
on b3.Y_id = y4.YId
left outer join [C] c5
on a0.C_id = c5.CId,
[B] b6
where a0.B_id = b6.BId
and (b6.X_id in (1, 2, 3, 4, 5))
order by a0.timestamp desc
如您所见,它获得了 3 次 a.b 的值 - b1 和 b3 用于获取,b6 用于 where 子句。
- 我认为这会对数据库性能产生负面影响 - 我是否正确?
- 有没有办法修改我的
.Fetch调用,使其只获取一次a.b? - 这是解决我的问题的好方法吗?
【问题讨论】:
标签: c# linq-to-nhibernate fetching-strategy