意外的批量更新命令后,选择在Nhibernate

本文关键字:选择 Nhibernate 命令 更新 意外 | 更新日期: 2023-09-27 18:18:33

我发现NHibernate在一些select之后会做出意想不到的更新。

实体:

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

I have try:

  • 启用/禁用延迟加载
  • 将级联更改为None,驱逐
  • 为ProductGroup引用设置Not.Update()
  • 使用Future<>

但仍然不能摆脱他们。

有人能解释一下为什么会出现这些更新命令吗?

意外的批量更新命令后,选择在Nhibernate

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; }

我的猜测是发生了自动刷新,NH认为这些ProductGroup对象由于某种原因是脏的。依我之见,最好的做法是通过log4net启用日志记录,并获得一些详细的诊断。NH的测井非常出色。你应该能够通过这个找到它的底部