我知道这是一个受欢迎的问题,并且已经向其他人提出了各种解决方案,但我的情况略有不同。
首先它从两天前开始突然发生,NHibernate层没有任何变化来解释这种行为的变化。
我使用了dotTrace并向下钻取,发现某些缓存查询最多需要70秒才能执行(即返回国家/地区对象列表的GetAllCountries()方法)。
对于没有外部引用的简单查询,70秒非常疯狂。
dotTrace显示它调用了CachedCountryService,它应该立即返回列表。相反,它最终会导致CountryService执行70秒的读取。
数据库是mySQL。
dotTrace报告的附加图片
Country对象如下所示:
public class CountryMapping : ClassMap<Country>
{
public CountryMapping()
{
Table("ma_tbl_country");
Id(t => t.Id, "id");
Map(t => t.Code, "code");
Map(t => t.Name, "name");
Map(t => t.Match, "`match`");
References(t => t.RiskGroup).Column("RiskId");
HasManyToMany(t => t.PaymentOptions)
.Table("ma_tbl_country_payment_option")
.ParentKeyColumn("country_id")
.ChildKeyColumn("payment_option_id").Cascade.SaveUpdate();
}
}
初始化程序不会影响国家/地区对象,尽管Office和帐户用于其他执行效果非常差的NHibernate查询(需要30秒)。
public NHibernateInitializer()
{
base.
ExtraConfiguration =
t =>
t.Mappings(s => s.FluentMappings.AddFromAssemblyOf<DAL.Mappings.OfficeMapping>().Conventions.Add(typeof(DisableLazyLoadConvention)))
.Mappings(s => s.FluentMappings.AddFromAssemblyOf<AccountMapping>().Conventions.Add(AutoImport.Never()));
}
DefaultLazyConvention是执行此操作的内部库的一部分:
public class DisableLazyLoadConvention : IHibernateMappingConvention, IConvention<IHibernateMappingInspector, IHibernateMappingInstance>, IConvention
{
public void Apply(IHibernateMappingInstance instance)
{
instance.Not.DefaultLazy();
}
}
更新:
我添加了SQL级别的分析,结果正在缓冲。
我有两个不同的项目运行相同的几乎代码,我在缓慢的项目中获得324个SQL查询需要100秒才能运行,然后在另一个项目中获得324个IDENTICAL查询需要1秒!
所以我认为问题是NHibernate配置,而不是代码,因为这两组查询使用相同的域模型是相同的。他们也使用相同的数据库和相同的数据库用户。
答案 0 :(得分:0)
从您的dotTrace屏幕截图中,请注意InitializeNonLazyCollections
几乎所有时间都在使用。
DisableLazyLoadConvention
的应用不仅仅是Office
。它将应用于与ClassMap
相同的程序集中的所有OfficeMapping
。约定用于在整个应用程序中以宽画笔描边应用映射。例如,您可以使用它们来说&#34;当您看到名称以&#39; Utc&#39;结尾的DateTime
属性时,请使用.CustomType("UtcDateTime")
进行映射。&#34 ;
如果您需要将特殊映射应用于一个类,请在ClassMap
(用于流畅映射)或IAutoMappingOverride
(用于自动映射)中执行此操作。如果要更改每个类的映射,请在使用约定时进行映射。
从您的NHibernate初始化代码中删除.Conventions.Add(typeof(DisableLazyLoadConvention))
,并将其替换为.Not.LazyLoad()
中对OfficeMapping
的更有针对性的调用。
答案 1 :(得分:0)
最终解决了这个问题。
这与NHibernate无关!这就是为什么它无法解决的原因。
问题是由名为Combres的这个包引起的。它通过Nuget安装,具有很多依赖性。在我的一个项目中,其中一个依赖项的版本略高于预期。
当我卸载并重新安装它时,它会放置正确的DLL版本(稍微较旧的版本)并使项目快速闪烁!
如果有人遇到这么难的问题,我希望这可以帮助他们解决问题。