【发布时间】:2011-03-24 01:13:12
【问题描述】:
我有一个带有集合的实体,它包含具有更多实体引用的其他实体。当实体被加载并稍后刷新时,延迟加载的集合被触发,并且从数据库中提取了很多我不需要的东西。那么如何防止刷新触发未初始化的集合呢? 我写了一个小测试来显示它。
class SimpleClass
{
public virtual int Id { get; set; }
public virtual IList<ChildClass> Childs { get; set; }
}
class ChildClass
{
public virtual int Id { get; set; }
}
class SimpleClassMap : ClassMap<SimpleClass>
{
public SimpleClassMap()
{
Id(sc => sc.Id).GeneratedBy.Assigned();
HasMany(sc => sc.Childs)
.Cascade.All()
.LazyLoad();
}
}
class ChildClassMap : ClassMap<ChildClass>
{
public ChildClassMap()
{
Id(cc => cc.Id).GeneratedBy.Assigned();
}
}
以及下面的测试
[Fact]
public void Test()
{
m_session.Save(new SimpleClass
{
Id = 1,
Childs = new List<ChildClass>
{
new ChildClass { Id = 1 },
new ChildClass { Id = 2 },
new ChildClass { Id = 3 },
}
});
m_session.Flush();
m_session.Clear();
log.Debug("Start Test");
var simple = m_session.Get<SimpleClass>(1);
var persistentcollection = simple.Childs as IPersistentCollection;
Assert.False(persistentcollection.WasInitialized, "Before Refresh, collection should not be initialized but was");
log.Debug("Refresh");
m_session.Refresh(simple);
Assert.False(persistentcollection.WasInitialized, "After Refresh, collection should not be initialized but was");
}
输出: 刷新后,集合不应该被初始化,而是被
澄清一下:
也许我可以在不删除 cascade.all 的情况下生活,但绝对不能没有 cascade.refresh。 如果已初始化,我希望刷新级联到集合,否则不会,因为它会在使用时延迟加载新数据。
我在刷新事件中使用了 NHibernate 代码。如果我删除提取配置文件:
DefaultRefreshEventListener {
public virtual void OnRefresh(RefreshEvent @event, IDictionary refreshedAlready)
{
[...]
string previousFetchProfile = source.FetchProfile;
//source.FetchProfile = "refresh";
object result = persister.Load(id, obj, @event.LockMode, source);
//source.FetchProfile = previousFetchProfile;
[...]
}
我在日志中得到了我期望的结果(删除了 SQL 中的别名):
不初始化集合
Session.Get
DEBUG - SELECT Id FROM "SimpleClass" WHERE Id=:p0;:p0 = 1
Refresh
DEBUG - SELECT Id FROM "SimpleClass" WHERE Id=:p0;:p0 = 1
使用初始化集合(simple.Childs.Count();)
Session.Get
DEBUG - SELECT Id FROM "SimpleClass" WHERE Id=:p0;:p0 = 1
simple.Childs.Count();
DEBUG - SELECT SimpleClass_id, Id, Id FROM "ChildClass" WHERE SimpleClass_id=:p0;:p0 = 1
Refresh
DEBUG - SELECT Id FROM "ChildClass" WHERE Id=:p0;:p0 = 1
DEBUG - SELECT Id FROM "ChildClass" WHERE Id=:p0;:p0 = 2
DEBUG - SELECT Id FROM "ChildClass" WHERE Id=:p0;:p0 = 3
DEBUG - SELECT Id FROM "SimpleClass" WHERE Id=:p0;:p0 = 1
我仍然不确定它的其他含义
【问题讨论】:
标签: c# nhibernate fluent-nhibernate