我正在使用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查询?
您的数据库架构和实体之间可能不匹配。您没有提供太多详细信息,所以下面是猜测。
可能的原因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 UpdatedByUser
和BaseEntity
属性。您有条件地从那里返回修改后的值。数据库SELECT查询最有可能返回一个值,而getter会将其更改为另一个。