为什么NHibernate使用QueryOver在简单的SELECT上执行UPDATE查询?

问题描述 投票:0回答:1

我正在使用NHibernate,Fluent-NHibernate和MYSQL5.7。

我有以下查询:

using(var session = factory.OpenSession())
{
    using(var tx = session.BeginTransaction())
    {
        roles = await session.QueryOver<SystemGroupRoleEntity>().Where(x => x.Group.Id == id).ListAsync();
        tx.Commit();
    }
}

以下是Entity和BaseEntity类:

public class SystemGroupRoleEntity : BaseEntity
{
    public virtual SystemRoleEntity Role { get; set; }
    public virtual SystemGroupEntity Group { get; set; }

}

public abstract class BaseEntity
{
    public virtual long? Id { get; set; }
    public virtual DateTime? DateCreated { get; set; } = null;
    public virtual DateTime? LastUpdatedDate { get; set; } = null;

    [JsonIgnore]
    public virtual SystemUserEntity CreatedBy { get; set; }

    [Newtonsoft.Json.JsonIgnore]
    public virtual SystemUserEntity LastUpdatedBy { get; set; }
    public virtual bool Deleted { get; set; } = false;


    [JsonProperty]
    public virtual UserDetails CreatedByUser
    {
        get
        {
            if(this.CreatedBy != null)
            {
                return new UserDetails(this.CreatedBy?.UserName, this.CreatedBy.Id);
            }
            else
            {
                return null;
            }
        }
    }

    [JsonProperty]
    public virtual UserDetails UpdatedByUser
    {
        get
        {
            if(this.LastUpdatedBy != null)
            {
                return new UserDetails(this.LastUpdatedBy?.UserName, this.LastUpdatedBy.Id);
            }
            else
            {
                return null;
            }
        }
    }
}

以下是我的映射:

public class BaseEntityMap<T> : ClassMap<T> where T : BaseEntity
{
    public BaseEntityMap()
    {
        Id(x => x.Id).GeneratedBy.Identity().Column("id");
        Map(x => x.DateCreated, "date_created").Nullable();
        Map(x => x.LastUpdatedDate, "last_updated_date").Nullable();
        Map(x => x.Deleted, "deleted");
        References(x => x.CreatedBy, "created_by").Cascade.Merge().Not.LazyLoad();
        References(x => x.LastUpdatedBy, "last_updated_by").Cascade.Merge().Nullable().Not.LazyLoad();
    }
}

public class SystemGroupRoleEntityMap : BaseEntityMap<SystemGroupRoleEntity>
{
    public SystemGroupRoleEntityMap()
    {
        Table("system_groups_roles_entity");
        References(x => x.Group).Cascade.All().Column("group_id").Not.LazyLoad().UniqueKey("groups_roles").Fetch.Join();
        References(x => x.Role).Cascade.All().Column("role_id").Not.LazyLoad().UniqueKey("groups_roles").Fetch.Join();

    }
}

当我运行上述查询时,NHibernate还在执行SystemGroupRoleEntity的UPDATE查询。

UPDATE system_role_entity SET date_created = ?p0, last_updated_date = ?p1, deleted = ?p2, name = ?p3, description = ?p4, is_super = ?p5, created_by = ?p6, last_updated_by = ?p7 WHERE id = ?p8;?p0 = NULL [Type: DateTime (0:0:0)], ?p1 = NULL [Type: DateTime (0:0:0)], ?p2 = False [Type: Boolean (0:0:0)], ?p3 = 'admin' [Type: String (5:0:0)], ?p4 = NULL [Type: String (0:0:0)], ?p5 = True [Type: Boolean (0:0:0)], ?p6 = NULL [Type: Int64 (0:0:0)], ?p7 = NULL [Type: Int64 (0:0:0)], ?p8 = 1 [Type: Int64 (0:0:0)]

为什么当我运行纯SELECT查询时为什么还会得到UPDATE查询?

mysql nhibernate fluent-nhibernate
1个回答
0
投票

您的数据库架构和实体之间可能不匹配。您没有提供太多详细信息,所以下面是猜测。

可能的原因1:模式和实体不匹配仔细查看您的UPDATE查询。一些参数值被传递NULL。您尚未提供实体类定义。映射到这些字段的属性也应该可以为空。现在,string(等效的DB类型VARCHAR)仍然可以为空。那还剩下什么呢?实体类别中date_created(可能DateTime)和deleted(可能bool)的数据类型是什么?分别是DateTime?bool??还要类似地检查其他属性。

这里的问题可能是数据库中那些字段的值为DbNull。映射属性的数据类型为bool,它不能保存null。您执行SELECT查询,结果被映射到您的实体。但是,DbNull无法映射到bool;因此,将考虑并分配默认值bool,即false。由于所选的值现在已更改;实体被标记为脏并且有资格在刷新时进行UPDATE。因此,您会看到意外的UPDATE查询。

可能的原因2:您正在更改实体构造函数中的属性值可能性很小,但只需确保您没有意外更改构造函数或其他地方(属性的获取/设置)的实体属性值。

查看UserDetails CreatedByUser类中的UserDetails UpdatedByUserBaseEntity属性。您有条件地从那里返回修改后的值。数据库SELECT查询最有可能返回一个值,而getter会将其更改为另一个。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.