在 Nhibernate 中选择后出现意外的批量更新命令 [重复]

Posted

技术标签:

【中文标题】在 Nhibernate 中选择后出现意外的批量更新命令 [重复]【英文标题】:Unexpected batch update commands after select in Nhibernate [duplicate] 【发布时间】:2017-04-02 12:59:17 【问题描述】:

我发现 NHibernate 在某些选择后会进行意外更新。

实体:

public class BasePriceRule : BaseEntity

    public virtual string Name  get; set; 

    public virtual string RuleString  get; set; 

    public virtual TypePriceRule Type  get; 

    public virtual DateTime Date  get; set;  = DateTime.Now;


public class ProductGroupRule : BasePriceRule

    public virtual ProductGroup ProductGroup  get; set; 

    public override TypePriceRule Type => TypePriceRule.ProductGroup;


public class ProductGroup : BaseEntity
        
    public virtual string Code  get; set; 

    public virtual string Name  get; set; 

    public virtual string Description  get; set; 

    public virtual UoM UoM  get; set; 

    public virtual CustomProductType Type  get; set; 

映射:

public class BasePriceRuleMap : ClassMap<BasePriceRule>

    public BasePriceRuleMap()
    
        Table("PriceRule");
        Id(x => x.Id);

        Map(x => x.Name);
        Map(x => x.RuleString).Length(4096);

        DiscriminateSubClassesOnColumn("Type");
        Map(x => x.Type).CustomType<TypePriceRule>().ReadOnly().Access.None().Not.Nullable();

        Map(x => x.Date).Not.Nullable().Default("CURRENT_TIMESTAMP");
    


public ProductGroupRuleMap()

    KeyColumn("Id");

    References(x => x.ProductGroup).Fetch.Join()/*.Not.Update()*/;
    DiscriminatorValue((int)TypePriceRule.ProductGroup);


public ProductGroupMap()

    Id(x => x.Id);

    Map(x => x.Code).Unique();
    Map(x => x.Name);
    Map(x => x.Description);
    Map(x => x.Type).CustomType<int>();

    References(x => x.UoM);

所以当我运行这个最简单的查询时:

_session.QueryOver<ProductGroupRule>();

或者这个:

_session.QueryOver<ProductGroupRule>().Fetch(x => x.ProductGroup).Eager.List();

我收到这个生成的 sql:

2016-11-18 17:17:39.3103 NHibernate.SQL  SELECT this_.Id as Id62_1_, this_.Name as Name62_1_, this_.RuleString as RuleString62_1_, this_.Type as Type62_1_, this_.ProductGroup_id as ProductG6_62_1_, productgro2_.Id as Id66_0_, productgro2_.Code as Code66_0_, productgro2_.Name as Name66_0_, productgro2_.Description as Descript4_66_0_, productgro2_.Type as Type66_0_, productgro2_.UoM_id as UoM6_66_0_ FROM PriceRule this_ left outer join [ProductGroup] productgro2_ on this_.ProductGroup_id=productgro2_.Id WHERE this_.Type='2'
2016-11-18 17:17:39.4474 NHibernate.SQL  Batch commands:
command 0:UPDATE [ProductGroup] SET Code = @p0, Name = @p1, Description = @p2, Type = @p3, UoM_id = @p4 WHERE Id = @p5;
command 1:UPDATE [ProductGroup] SET Code = @p0, Name = @p1, Description = @p2, Type = @p3, UoM_id = @p4 WHERE Id = @p5;
--Numbers of commands are equal to the amount of records in PriceRule table

我试过了:

启用/禁用延迟加载 将级联更改为无,逐出 为 ProductGroup 参考设置 Not.Update() 使用未来

但仍然无法摆脱它们。

谁能解释为什么会出现这些更新命令?

【问题讨论】:

【参考方案1】:

ProductGroup定义中,有一个属性,不能为null——CustomProductType Type

public class ProductGroup : BaseEntity
        
    public virtual string Code  get; set; 
    public virtual string Name  get; set; 
    public virtual string Description  get; set; 
    public virtual UoM UoM  get; set; 
    // this cannot be null
    public virtual CustomProductType Type  get; set; 

C# 会将其设置为默认值(通常是第一个 enum

但似乎在 DB 中,相关列包含 null。对于 NHibernate,它是一个标志:1) 加载时为 NULL,但在检查对象时 - 2) 它具有分配的值。

所以,对象是脏的,因为 Flush 模式默认为 AUTO ...它试图保持 DB 和 C# 实例同步

只需更改映射

    public virtual CustomProductType? Type  get; set; 

【讨论】:

这有点奇怪,因为实际上我在数据库中没有空类型的 ProductGroups。无论如何将属性设置为 Nullable 或相反将映射配置更改为 Not.Nullable 删除更新语句。谢谢 这是捉鬼敢死队原始代码的链接。 joseoncode.com/2010/02/05/nhibernate-ghostbuster-version-1-1 这是查找此类问题的好工具,不确定它是否可以与当前版本的 nhibernate 一起运行。【参考方案2】:

我的猜测是发生了自动刷新,NH 认为那些 ProductGroup 对象由于某种原因是脏的。恕我直言,最好的做法是通过 log4net 发送至enable logging 并获得一些详细的诊断信息。 NH的日志记录非常好。你应该能够通过它来追根究底。

【讨论】:

以上是关于在 Nhibernate 中选择后出现意外的批量更新命令 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

NHibernate中的批量更新

NHibernate左连接选择计数在一对多关系中

NHibernate 似乎没有批量插入 PostgreSQL

删除后休眠意外行数上升

踩坑了!踩坑了!NHibernate使用批量插入Oracle数据,Batch属性

beginUpdates/endUpdates 后出现意外的表格单元格动画