.net 如何解决nHibernate集合初始化不佳的问题
nHibernate3;从EAV数据架构中检索4xxx记录。当nHibernate或.NET第一次去初始化这些集合时,我们看到了一个严重的惩罚。后续调用的执行效率似乎更高。在SQLServerManagementStudio中运行相同的查询会导致预期的快速返回时间 使用Fluent和runtime映射代替.hbm.xml;想知道序列化映射在这里是否有用吗 nHibernate Profiler和log4net日志似乎并没有给我太多的东西。在这个过程中,总共有大约140000个实体被水合 附加了my dotTrace性能跟踪的屏幕截图,其中显示了集合初始化惩罚: 已经尝试了join和Earge FetchType,但没有明显的结果,但我不能100%确定我正确地实现了它们——是否只需要这样指定父表,还是也需要标记子表.net 如何解决nHibernate集合初始化不佳的问题,.net,nhibernate,fluent-nhibernate,nhibernate-criteria,.net,Nhibernate,Fluent Nhibernate,Nhibernate Criteria,nHibernate3;从EAV数据架构中检索4xxx记录。当nHibernate或.NET第一次去初始化这些集合时,我们看到了一个严重的惩罚。后续调用的执行效率似乎更高。在SQLServerManagementStudio中运行相同的查询会导致预期的快速返回时间 使用Fluent和runtime映射代替.hbm.xml;想知道序列化映射在这里是否有用吗 nHibernate Profiler和log4net日志似乎并没有给我太多的东西。在这个过程中,总共有大约140000个实体被水合 附加了m
var products = ((HandleSession)_handleSession).Session.CreateCriteria(typeof(Product))
.SetFetchMode("Product", FetchMode.Eager)
.List<Product>()
.AsEnumerable();
这是一种简单的扩展方法,用于:
public static ProductContract ToProductContract(this Product product)
{
return new ProductContract
{
Name = product.ProductName,
ProductTypeName = product.ProductType.ProductTypeName,
UpdateTimeStamp = product.UpdateDateTime,
ProductNumber = product.ProductNumber,
Attributes = product.ProductAttributes.ToCommonAttribute().ToList(),
GroupCategories = product.ProductGroups.ToGroupCategory().ToList(),
PublicUniqueId = product.PublicUniqueId
};
}
映射:
internal class ProductMapping : ClassMap<Product>
{
private const string _iscurrentindicator = "IsCurrentIndicator=1";
public ProductMapping()
{
Table("Product");
Id(Reveal.Member<Product>("ProductId")).GeneratedBy.Identity().Column("ProductID");
Map(x => x.ProductNumber).Column("ProductNumber").Not.Nullable();
Map(x => x.ProductName).Column("ProductName").Not.Nullable();
Map(x => x.InsertDateTime).Column("InsertedDateTime").Nullable().ReadOnly();
Map(x => x.UpdateDateTime).Column("UpdatedDateTime").Nullable();
Map(x => x.PublicUniqueId).Column("ProductGUID").Generated.Insert();
References(x => x.ProductType).Column("ProductTypeId").Not.Nullable();
HasMany(x => x.ProductAttributes)
.KeyColumn("ProductId")
.Inverse()
.Fetch
.Subselect()
.Where(_iscurrentindicator)
.Cascade
.SaveUpdate();
HasMany(x => x.ProductGroups).KeyColumn("ProductId").Fetch.Subselect().Where(_iscurrentindicator);
DynamicUpdate();
DynamicInsert();
BatchSize(500);
}
}
internal class ProductGroupMapping : ClassMap<ProductGroup>
{
public ProductGroupMapping()
{
Table("ProductGroup");
Id(x => x.ProductGroupId).Column("ProductGroupId").GeneratedBy.Identity();
References(x => x.Product).Column("ProductId").Not.Nullable();
References(x => x.Group).Column("GroupId").Not.Nullable();
//Where("IsCurrentIndicator=1");
}
}
internal class ProductAttributeMapping : ClassMap<ProductAttribute>
{
public ProductAttributeMapping()
{
Table("ProductAttribute");
LazyLoad();
Id(x => x.ProductAttributeId).GeneratedBy.Identity().Column("ProductAttributeID");
References(x => x.Product).Column("ProductID").Not.Nullable();
References(x => x.Attribute).Column("AttributeID").Not.Nullable().Fetch.Join();
Map(x => x.PositionNumber).Column("PositionNumber").Nullable();
Map(x => x.ValueText).Column("ValueText").Nullable();
Map(x => x.ValueBinary).Column("ValueBinary").Nullable();
Component(x => x.OperationalAuditHistory, m =>
{
Table("ProductAttribute");
m.Map(x => x.ExpirationDateTime).Column("ExpirationDateTime").Nullable();
m.Map(x => x.IsCurrent).Column("IsCurrentIndicator").Not.Nullable();
m.Map(x => x.OperationCode).Column("OperationCode").Nullable();
m.Map(x => x.OperationDateTime).Column("OperationDateTime").Nullable();
m.Map(x => x.OperationSystemName).Column("OperationSystemName").Nullable();
m.Map(x => x.OperationUserName).Column("OperationUserName").Nullable();
m.Map(x => x.LastUserPriority).Column("LastUserPriority").Nullable();
});
DynamicInsert();
BatchSize(50);
}
}
内部类ProductMapping:ClassMap
{
私有常量字符串_iscurrentindicator=“iscurrentindicator=1”;
公共产品映射()
{
表(“产品”);
Id(leaver.Member(“ProductId”)).GeneratedBy.Identity()列(“ProductId”);
Map(x=>x.ProductNumber).Column(“ProductNumber”).Not.Nullable();
映射(x=>x.ProductName).Column(“ProductName”).Not.Nullable();
映射(x=>x.InsertDateTime).Column(“InsertedDateTime”).Nullable().ReadOnly();
Map(x=>x.UpdateDateTime).Column(“UpdateDateTime”).Nullable();
Map(x=>x.PublicUniqueId).Column(“ProductGUID”).Generated.Insert();
引用(x=>x.ProductType).Column(“ProductTypeId”).Not.Nullable();
HasMany(x=>x.ProductAttributes)
.KeyColumn(“ProductId”)
.Inverse()
取来
.Subselect()
.Where(\u是电流指示器)
大量
.SaveUpdate();
HasMany(x=>x.ProductGroups).KeyColumn(“ProductId”).Fetch.Subselect()。其中(\u iscurrentindicator);
DynamicUpdate();
DynamicInsert();
批量大小(500);
}
}
内部类ProductGroupMapping:ClassMap
{
公共产品组映射()
{
表(“产品组”);
Id(x=>x.ProductGroupId).Column(“ProductGroupId”).GeneratedBy.Identity();
引用(x=>x.Product).Column(“ProductId”).Not.Nullable();
引用(x=>x.Group).Column(“GroupId”).Not.Nullable();
//其中(“IsCurrentIndicator=1”);
}
}
内部类ProductAttributeMapping:ClassMap
{
公共产品属性映射()
{
表(“ProductAttribute”);
懒散的负荷();
Id(x=>x.ProductAttributeId).GeneratedBy.Identity()列(“ProductAttributeId”);
引用(x=>x.Product).Column(“ProductID”).Not.Nullable();
引用(x=>x.Attribute).Column(“AttributeID”).Not.Nullable().Fetch.Join();
Map(x=>x.PositionNumber).Column(“PositionNumber”).Nullable();
Map(x=>x.ValueText).Column(“ValueText”).Nullable();
Map(x=>x.ValueBinary).Column(“ValueBinary”).Nullable();
组件(x=>x.0,m=>
{
表(“ProductAttribute”);
m、 Map(x=>x.ExpirationDateTime).Column(“ExpirationDateTime”).Nullable();
m、 Map(x=>x.IsCurrent).Column(“IsCurrentIndicator”).Not.Nullable();
m、 Map(x=>x.OperationCode).Column(“OperationCode”).Nullable();
m、 映射(x=>x.OperationDateTime).Column(“OperationDateTime”).Nullable();
m、 映射(x=>x.OperationSystemName).Column(“OperationSystemName”).Nullable();
m、 Map(x=>x.OperationUserName).Column(“OperationUserName”).Nullable();
m、 Map(x=>x.LastUserPriority).Column(“LastUserPriority”).Nullable();
});
DynamicInsert();
批量大小(50);
}
}
不幸的是,在未来,我似乎仍然得到类似的结果。这里有一个新的痕迹;目前,我已经切换到发行版,关键项目使用x64,因此时间更短,但比例仍然基本相同;以及。渴望:
var products = ((HandleSession) _handleSession).Session.CreateCriteria(typeof (Product))
.SetFetchMode("ProductAttribute", FetchMode.Join)
.SetFetchMode("ProductGroup", FetchMode.Join)
.SetFetchMode("ProductType", FetchMode.Join)
.Future<Product>()
.AsEnumerable();
var products=((HandleSession)\u HandleSession.Session.CreateCriteria(产品类型))
.SetFetchMode(“ProductAttribute”,FetchMode.Join)
.SetFetchMode(“ProductGroup”,FetchMode.Join)
.SetFetchMode(“ProductType”,FetchMode.Join)
.Future()
.AsEnumerable();
使用.Eager和.Future生成SQL:
选择此产品ID作为
ProductID0\u 1\u,此产品编号为
产品2\u 0\u 1,此产品名为
ProductN3\u 0\u 1\u,此\u.InsertedDateTime
插入4_0_1_,
此更新的DateTime为
UpdatedD5\u 0\u 1\u,此\u.ProductGUID为
ProductG6\u 0\u 1\u,此\u.ProductTypeId为
产品7\u 0\u 1\u,
producttyp2\产品类型ID为
产品1\u 6\u 0\u,
producttyp2\产品类型名称为
此产品的产品2\u 6\u 0_
内部联接ProductType producttyp2_uuon
此_u.ProductTypeId=productType2_u.ProductTypeId
选择productatt0\uU0.ProductId作为
产品ID2,
productatt0_u0.ProductAttributeID为
产品1\u 2\u,
productatt0_u0.ProductAttributeID为
产品1\u 2\u 1\u,
产品ATT0位置编号为
位置2\u 2\u 1\u,产品ATT0\u。值文本
作为ValueText2\u 1\u,
productatt0\ uU0.ValueBinary作为
ValueBin4\u 2\u 1\u,productatt0\u.ProductID
作为产品ID2\u 1\u,
productatt0_uu0.AttributeID as
属性6_2_1_,
productatt0\过期日期时间为
到期日,
普罗杜
var products = ((HandleSession) _handleSession).Session.CreateCriteria(typeof (Product))
.SetFetchMode("ProductAttribute", FetchMode.Join)
.SetFetchMode("ProductGroup", FetchMode.Join)
.SetFetchMode("ProductType", FetchMode.Join)
.Future<Product>()
.AsEnumerable();
var products = ((HandleSession)_handleSession).Session.CreateCriteria(typeof(Product))
.SetFetchMode("ProductChildren", FetchMode.Eager)
.List<Product>()
.AsEnumerable();
// any where-condition will have to be applied here and in the subsequent queries
var products = session.QueryOver<Product>()
.Future();
var products2 = session.QueryOver<Product>()
.Fetch(p => p.ProductType).Eager
.Future();
var products3 = session.QueryOver<Product>()
.Fetch(p => p.ProductAttributes).Eager
.Future();
var products4 = session.QueryOver<Product>()
.Fetch(p => p.ProductGroups).Eager
.Future();
// Here we execute all of the above queries in one roundtrip.
// Since we already have all the data we could possibly want, there is no need
// for a N+1 Select.
return new ProductList(products.Select(p => p.ToProductContract()));
Session.FlushMode = FlushMode.Never;