You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NHibernate 升级至5.2版本后多对多关联过滤器失效问题

NHibernate 升级至5.2版本后多对多关联过滤器失效问题

我看了你升级NHibernate从5.1.7到5.2.0时遇到的多对多关联过滤器失效问题,结合你贴的代码,咱们来捋捋原因和解决思路:

问题现象回顾

在旧版本(5.1.7及以下)中,用session.Get<Webcam>(123241)获取实体后,webcamByGet.Supplies.Count返回0——这符合预期,因为你给Webcam和Supply都设置了DeletedAt值,过滤器本该把这些已标记删除的关联项过滤掉。但升级到5.2.0+后,这个计数不为0,说明多对多关联上的过滤器没生效。

可能的原因

NHibernate 5.2版本对多对多关联的过滤器处理逻辑做了调整,尤其是延迟加载集合的初始化阶段,之前的ApplyChildFilter方法可能不再正确把过滤条件传递到集合加载的SQL查询里,导致过滤器没起作用。

解决办法

试试下面这几个调整方案:

  • 替换ApplyChildFilter为ApplyFilter
    在你的多对多映射配置里,把ApplyChildFilter<DeletedAtIsNullFilterConvention.NotDeletedFilter>()替换成ApplyFilter<DeletedAtIsNullFilterConvention.NotDeletedFilter>()。比如修改WebcamMap里的关联配置:

    HasManyToMany(x => x.Supplies)
       .Schema("mod_list_management")
       .Table("DynSuppliesWebcams")
       .ParentKeyColumn("WebcamId")
       .ChildKeyColumn("SupplyId")
       .ApplyFilter<DeletedAtIsNullFilterConvention.NotDeletedFilter>() // 替换原ApplyChildFilter
       .Cascade.All();
    

    同样的,SupplyMap里的多对多关联也做相同替换。

  • 确认过滤器的注册和启用时机
    你已经在代码里调用了session.EnableFilter(DeletedAtIsNullFilterConvention.NotDeletedFilter.FilterName),但要确保这行代码是在加载集合之前执行的。另外检查CreateSessionFactory里是否正确注册了过滤器:Add(typeof(DeletedAtIsNullFilterConvention.NotDeletedFilter))这一步没问题,但可以确认下过滤器的定义是否正确,比如过滤条件是不是DeletedAt IS NULL(对应你设置的DeletedAt = DateTime.UtcNow,应该被过滤)。

  • 调试生成的SQL语句
    你已经开启了ShowSql(),运行代码时仔细看加载Supplies集合的SQL语句,有没有包含DeletedAt IS NULL的过滤条件。如果没有,说明过滤器确实没被应用到集合查询中,这时候要重点检查映射配置里的过滤器应用方式。

  • 显式初始化集合
    因为你的集合是延迟加载的,5.2版本中延迟加载的初始化逻辑可能有变化,可以尝试显式初始化集合后再检查计数:

    var webcamByGet = session.Get<Webcam>(123241);
    NHibernate.NHibernateUtil.Initialize(webcamByGet.Supplies); // 显式初始化
    var count2 = webcamByGet.Supplies.Count;
    

验证

修改配置后重新运行测试代码,观察count2是否回到预期的0,同时看生成的SQL是否包含过滤条件,确认过滤器生效。

备注:内容来源于stack exchange,提问作者Sahin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 12:05:32