Nhibernate 转换为按代码映射会导致严重的性能问题
我有一个NHibernate项目,它使用映射配置文件。我正在使用SQL Server数据库 我想切换到代码映射。我的方法是一次完成一个类,确认每次转换时所有测试都通过 混合使用这两种映射非常困难:Nhibernate 转换为按代码映射会导致严重的性能问题,nhibernate,mapping-by-code,Nhibernate,Mapping By Code,我有一个NHibernate项目,它使用映射配置文件。我正在使用SQL Server数据库 我想切换到代码映射。我的方法是一次完成一个类,确认每次转换时所有测试都通过 混合使用这两种映射非常困难: public static ISessionFactory SessionFactory { get { if (_sessionFactory == null) { var configuration = new Co
public static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
var configuration = new Configuration();
configuration.Configure();
configuration.AddAssembly(typeof(Entities.Player).Assembly);
var mapper = new NHibernate.Mapping.ByCode.ModelMapper();
// Here are the entities I've switched to mapping-by-code
DATMedia.CMS.EntityLibrary.Mappings.ScheduleMediaItem.Map(mapper);
DATMedia.CMS.EntityLibrary.Mappings.Schedule.Map(mapper);
configuration.AddMapping(mapper.CompileMappingForAllExplicitlyAddedEntities());
_sessionFactory = configuration.BuildSessionFactory();
}
return _sessionFactory;
}
}
然而,当我将映射更改为按代码映射时,我遇到了重大的性能问题。调用Session.Flush
需要12秒,而这需要少量的测试数据
我切换回XML映射,性能问题消失了
还有其他人遇到过这个问题吗
我将包括计划
的前后映射,以防出现明显的缺陷:
通过配置文件:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="DATMedia.CMS.EntityLibrary.Entities.Schedule, DATMedia.CMS.EntityLibrary" table="cms_Schedule">
<id name="Id" column="Id" type="Int64">
<generator class="identity" />
</id>
<property name="Date" column="Date" type="Timestamp" />
<many-to-one name="SourceTemplate" column="SourceTemplate_Id" class="DATMedia.CMS.EntityLibrary.Entities.ScheduleTemplate, DATMedia.CMS.EntityLibrary" cascade="none" fetch="join" lazy="proxy"/>
<!--
Note that we are not using cascading deletes here.
This will be handled by SQL Server through ON DELETE CASCADE foreign key constraints
-->
<bag name="MediaItems" inverse="true" cascade="save-update" lazy="true" order-by="PlayIndex">
<key column="Schedule_Id" />
<one-to-many class="DATMedia.CMS.EntityLibrary.Entities.ScheduleMediaItem, DATMedia.CMS.EntityLibrary"/>
</bag>
<bag name="PlayerGroups" table="cms_ManyToMany_PlayerGroupSchedules_PlayerGroup_Schedule" lazy="true" cascade="save-update">
<key column="Schedule_Id" />
<many-to-many column="PlayerGroup_Id"
class="DATMedia.CMS.EntityLibrary.Entities.PlayerGroup, NHibernateManyToMany" />
</bag>
</class>
</hibernate-mapping>
以及代码映射:
public static void Map(ModelMapper mapper)
{
mapper.Class<DATMedia.CMS.EntityLibrary.Entities.Schedule>(
classMapper =>
{
classMapper.Table("cms_Schedule");
classMapper.Id(x => x.Id, map =>
{
map.Column("Id");
map.Generator(Generators.Identity);
});
classMapper.Property(
s => s.Date,
propertyMapper =>
{
propertyMapper.Column("Date");
propertyMapper.NotNullable(true);
}
);
classMapper.ManyToOne(
s => s.SourceTemplate,
manyToOneMapper =>
{
manyToOneMapper.Column("SourceTemplate_Id");
manyToOneMapper.Cascade(Cascade.None);
manyToOneMapper.Fetch(FetchKind.Join);
manyToOneMapper.Lazy(LazyRelation.Proxy);
}
);
classMapper.Bag(
s => s.MediaItems,
bagPropertyMapper =>
{
bagPropertyMapper.Key(keyMapper =>
{
keyMapper.Column("Schedule_Id");
}
);
bagPropertyMapper.Inverse(true);
bagPropertyMapper.Cascade(Cascade.Persist);
bagPropertyMapper.Lazy(CollectionLazy.Lazy);
bagPropertyMapper.OrderBy(smi => smi.PlayIndex);
}
);
classMapper.Bag(
s => s.PlayerGroups,
bagPropertyMapper =>
{
bagPropertyMapper.Key(keyMapper =>
{
keyMapper.Column("Schedule_Id");
});
bagPropertyMapper.Table("cms_ManyToMany_PlayerGroupSchedules_PlayerGroup_Schedule");
bagPropertyMapper.Lazy(CollectionLazy.Extra);
bagPropertyMapper.Cascade(Cascade.Persist);
},
collectionElementRelation =>
{
collectionElementRelation.ManyToMany(manyToManyMapper =>
{
manyToManyMapper.Column("PlayerGroup_Id");
}
);
}
);
}
);
}
publicstaticvoid映射(ModelMapper映射器)
{
映射器类(
类映射器=>
{
类映射表(“cms_计划”);
classMapper.Id(x=>x.Id,map=>
{
地图栏(“Id”);
map.Generator(Generators.Identity);
});
classMapper.Property(
s=>s.日期,
propertyMapper=>
{
propertyMapper.列(“日期”);
propertyMapper.NotNullable(true);
}
);
classMapper.ManyToOne(
s=>s.SourceTemplate,
ManyToneMapper=>
{
manyToOneMapper.Column(“SourceTemplate_Id”);
manyToOneMapper.Cascade(Cascade.None);
manyToOneMapper.Fetch(FetchKind.Join);
manyToOneMapper.Lazy(LazyRelation.Proxy);
}
);
类映射器。包(
s=>s.MediaItems,
bagPropertyMapper=>
{
bagPropertyMapper.Key(keyMapper=>
{
keyMapper.列(“附表_Id”);
}
);
bagPropertyMapper.反向(真);
bagPropertyMapper.Cascade(Cascade.Persist);
bagPropertyMapper.Lazy(CollectionLazy.Lazy);
bagPropertyMapper.OrderBy(smi=>smi.PlayIndex);
}
);
类映射器。包(
s=>s.PlayerGroups,
bagPropertyMapper=>
{
bagPropertyMapper.Key(keyMapper=>
{
keyMapper.列(“附表_Id”);
});
bagPropertyMapper.表格(“cms_manytomy_PlayerGroup schedules_PlayerGroup_Schedule”);
bagPropertyMapper.Lazy(CollectionLazy.Extra);
bagPropertyMapper.Cascade(Cascade.Persist);
},
CollectionElementralation=>
{
collectionElementRelation.ManyToMany(manyToManyMapper=>
{
manyToManyMapper.Column(“PlayerGroup_Id”);
}
);
}
);
}
);
}
以后编辑
我通过在事务中不调用Flush
解决了这个问题
我试图创建一些简单的测试代码来复制这个问题,但没有成功(无论我调用Flush多少次,我所有的测试代码都运行得非常快)。这可能是因为我将某些实体的密钥生成从Identity
转换为HiLo
所以在我的例子中,我的代码创建了一个特定的配置,这带来了一个问题,希望这不会再次困扰我
如果我猜得到的话,我会说导致问题的配置包括对长时间运行的事务的轻率使用以及身份密钥生成。我在很多项目中使用了混合映射,并且没有遇到您描述的任何问题。我不明白为什么冲洗需要12秒
我的混合映射技术与您的略有不同,我不能100%确定您配置的顺序是否重要,值得一试。看
我认为您已经导出了所有映射,并再次检查它们在前后是否相同。看