NHibernate を使用して Web アプリからクエリを実行している階層データを保持するテーブルがあります。それはかなり簡単です
CREATE TABLE [dbo].[Relationships](
[RelationshipId] [uniqueidentifier] NOT NULL,
[ParentId] [uniqueidentifier] NULL,
[ParentTypeId] [uniqueidentifier] NULL,
[ChildId] [uniqueidentifier] NOT NULL,
[ChildTypeId] [uniqueidentifier] NOT NULL
)
このテーブルから情報をクエリするために、Common Table Expressions (略して CTE) と呼ばれる SQL Server (2005 年以降) の機能を使用しています。上記のようなテーブルに非常に役立つ再帰クエリを作成できます。
WITH Ancestors(RelationshipId, ParentId, ChildId)
AS
(
SELECT r.RelationshipId, r.ParentId, r.ChildId
FROM Relationships r
WHERE ChildId = :objectId
UNION ALL
SELECT r.RelationshipId, r.ParentId, r.ChildId
FROM Relationships r
INNER JOIN Ancestors
ON Ancestors.ParentId = r.ChildId
)
SELECT RelationshipId, ParentId, ChildId FROM Ancestors
さて、これは素晴らしいことであり、パフォーマンスはそれほど悪くはありませんが、これを使用してツリーを上る先祖を特定しようとすると、またはさらに悪いことに、同様のクエリを使用して子孫を特定しようとすると、負担がかかる可能性があります。
ここで、このクエリの結果を単純にキャッシュしたいのですがIndex was outside the bounds of the array.
、.SetCacheable(true)
. キャッシュのサポートを削除すると、クエリは正常に機能します。
への呼び出しからキャッシング サポートを削除すると、クエリは正常に機能しSession.CreateSQLQuery()
ます。オンラインで原因を調べてみましたが、見つかった結果の中でコンセンサスが見つかりませんでした。
なぜうまくいかないのか知りたいのですが、nHibernate の CTE でキャッシングを機能させるための回避策を見つけることにもっと興味がありますか?