我的模型看起来像这样:
public class ComponentAttributeDto
{
public virtual long ComponentAttributeId { get; set; }
public virtual ComponentAttributeDto ParentComponentAttributeDto { get; set; }
public virtual string ComponentAttributeName { get; set; }
public virtual string Value { get; set; }
public virtual DataType DataType { get; set; }
public virtual IList<ComponentAttributeDto> ChildComponentAttributes { get; set; }
}
使用映射文件:
public class ComponentAttributeMapping : ClassMap<ComponentAttributeDto>
{
public ComponentAttributeMapping()
{
Table("ComponentAttributes");
Id(x => x.ComponentAttributeId)
.GeneratedBy.Identity();
References(x => x.ParentComponentAttributeDto)
.Column("ParentComponentAttributeId");
HasMany(x => x.ChildComponentAttributes)
.Fetch.Select()
.Inverse()
.Cascade.AllDeleteOrphan()
.KeyColumn("ParentComponentAttributeId");
Map(x => x.ComponentAttributeName)
.Length(50);
Map(x => x.Value)
.Length(1500);
Map(x => x.DataType)
.Length(20);
}
}
当使用大约4级深度的大型数据集加载时,性能非常糟糕。运行探查器时,我注意到它是为表中要查找的数据的每个值执行一个select语句。有没有办法可以提高性能,以便在表格或其他方面进行某种类型的连接?
答案 0 :(得分:1)
您可以使用batch-size预取实例,这会大大减少查询次数。
映射(不确定Fluent是否同时支持):
HasMany(x => x.ChildComponentAttributes)
.Fetch.Select()
.SetAttribute("batch-size", "20")
.Inverse()
.Cascade.AllDeleteOrphan()
.KeyColumn("ParentComponentAttributeId");
如果您有Root属性,则可以立即查询整个树。
public class ComponentAttributeDto
{
public virtual ComponentAttributeDto ParentComponentAttributeDto { get; private set; }
public virtual ComponentAttributeDto Root
{
get
{
if (ParentComponentAttributeDto == null)
{
return this;
}
else
{
return ParentComponentAttributeDto.Root;
}
}
private set
{ /* just for NH to call it */ }
}
// ....
}
HasMany(x =&gt; x.Children).AsSet()。SetAttribute(“batch-size”,“20”)
查询
session.CreateQuery(
@"from ComponentAttributeDto
where Root = :root"
.SetEntity(root);
实际上应该只导致一个查询。不确定NH是否实际上不对列表执行查询(ChildComponentAttributes),但值得一试。
答案 1 :(得分:0)
您是否一次需要整个数据结构?通常当我遇到这个问题时,我只是从nHibernate中取走映射处理并自己处理它。为名为getChildren()的类创建一个方法,让它在调用时运行查询。如果要添加子记录,则添加另一个名为addChild()的方法,并使用它自己的父ID进行实例化。
答案 2 :(得分:0)
您可以在查询时急切地获取层次结构。您可以使用查询中的eager fetch选项执行此操作:
Session.QueryOver<ComponentAttributeDto>
.Fetch(a => a.ChildComponentAttributes).Eager
降低到你想要的等级。