除非在映射文件中指定延迟加载,否则缓存不适用于关联实体

时间:2010-08-24 11:01:14

标签: nhibernate

我遇到问题,除非相关实体被缓存 它们被指定(映射中的Not.LazyLoad())。如果我建立一个查询 在Criteria或Linq中,主要实体被缓存,但没有关联 实体。

IList<NewsItem> news;
using (var session = factory.OpenSession())
{
    Console.WriteLine("First Query");
    news = session.CreateCriteria(typeof(NewsItem))
        .SetCacheable(true)
        .SetFetchMode("Author", FetchMode.Eager) // associated entity eager loaded
        .List<NewsItem>();
}
foreach (var item in news)
{
    Console.WriteLine("Author: " + item.Author.Name); //works fine first time
}

using (var session = factory.OpenSession())
{
    Console.WriteLine("");
    Console.WriteLine("Second Query");
    news = session.CreateCriteria(typeof(NewsItem))
        .SetCacheable(true)
        .SetFetchMode("Author", FetchMode.Eager)
        .List<NewsItem>();
}
foreach (var item in news)
{
    Console.WriteLine("Author: " + item.Author.Name); //NHibernate.LazyInitializationException
}

我想避免通过映射急于加载关联 文件。其他人有类似的问题。

任何反馈意见。

1 个答案:

答案 0 :(得分:0)

查询缓存(SetCacheable(true))的作用是存储查询检索到的 ID ;然后它逐个水合对象(希望来自实体缓存)。

IIRC,在缓存查询时,不使用相关entites的FetchModes,因此没有初始化Author引用。

值得注意的是,您不应该在会话之外使用您的实体,但这是一种解决方法:

news = session.CreateCriteria(typeof(NewsItem))
              .SetCacheable(true)
              .SetFetchMode("Author", FetchMode.Eager)
              .List<NewsItem>();
foreach (var item in news)
{
    var name = item.Author.Name;
}

这将强制初始化会话内的代理;那样你以后就可以使用它们了。

当然,您需要确保同时缓存NewsItem和Author,否则您实际上会通过缓存查询来降低性能。