2012-02-12 62 views
3

TransactionException:未连接事务,或线路被断开] NHibernate.Transaction.AdoTransaction.CheckNotZombied()108
NHibernate.Transaction.AdoTransaction.Rollback()144功能NHibernate枚举与映射复合键 - CheckNotZombied

同时使用NHibernate通过以下方式进行查询,而我得到上述错误:

public IEnumerable<Service> GetAllServicesByOrgType(OrganisationType orgType) 
{ 
return NHibernateSession 
    .CreateCriteria<ServiceOrganisationType>() 
    .Add(Restrictions.Eq("OrganisationType", orgType))    
    .List<ServiceOrganisationType>() 
      .Select(x=>x.Service); 
} 

下面是我的数据库结构和FluentNHibernate映射和模型:

数据库结构

Service: 
- Id(PK) 
- Name (nvarchar) 

ServiceOrganisationType (composite PK on OrganisationTypeId and ServiceId): 
- OrganisationTypeId (PK) 
- ServiceId (PK) 
- LastUpdated 
- LastUpdatedById 

OrganisationType: 
- Id (PK) 
- OrganisationType (nvarchar) 

ServiceOrganisationTypeMap:

public class ServiceOrganisationTypeMap : ClassMap<ServiceOrganisationType> 
{ 
    public ServiceOrganisationTypeMap() 
    { 
     CompositeId() 
      .KeyReference(x => x.Service, "ServiceId") 
      .KeyProperty(x => x.OrganisationType, "OrganisationTypeId"); 
     References(x => x.LastUpdatedBy); 
     Map(x => x.LastUpdated); 
    } 
} 

ServiceMap:

public class ServiceMap : ClassMap<Service> 
{ 
    /// <summary> 
    /// Initializes a new instance of the ServiceMap class. 
    /// </summary> 
    public ServiceMap() 
    { 
     Id(x => x.Id).GeneratedBy.Identity(); 
     Map(x => x.Name); 
     HasMany(x => x.ServiceOrganisationTypes) 
      .KeyColumn("ServiceId") 
      .Inverse() 
      .Cascade 
      .AllDeleteOrphan(); 

     // Other mappings... 
    } 
} 

OrganisationType是一个枚举:

public enum OrganisationType : long 
{ 
    FirstOrgTypeExample = 1, 
    SecondOrgTypeExample = 10, 
    ThirdOrgTypeExample = 30 
} 

服务模型类:

[Serializable] 
public class Service : DomainObject 
{ 
    // Other model properties... 

    public virtual IList<ServiceOrganisationType> ServiceOrganisationTypes { get; set; } 
} 

ServiceOrganisationType模型类:

[Serializable] 
public class ServiceOrganisationType : AuditedObject 
{ 
    [NotNull] 
    public virtual OrganisationType OrganisationType { get; set; } 

    [NotNull] 
    public virtual Service Service { get; set; } 

    public override bool Equals(object obj) 
    { 
     if (obj == null) 
      return false; 
     var t = obj as ServiceOrganisationType; 
     if (t == null) 
      return false; 
     if (OrganisationType == t.OrganisationType && Service == t.Service) 
      return true; 
     return false; 
    } 

    public override int GetHashCode() 
    { 
     return (OrganisationType + "|" + Service.Id).GetHashCode(); 
    } 
} 

对于枚举,我还使用这个职位的答案中所描述的EnumConvention类:Enum to integer mapping causing updates on every flush。所以我的接受方法有以下内容:

public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) 
{ 
    criteria.Expect(
     // ... Other arguments || 

     // We want all instance of OrganisationType to map to long 
     x.Property.PropertyType == typeof(OrganisationType) 

     ); 
} 

我猜测CheckNotZombied是别的症状。当我检查NHProf它显示了一个SQL错误 - “System.Data.SqlClient.SqlException:错误转换数据类型为nvarchar为bigint” - 这NHib生成以下SQL而查询表ServiceOrganisationType:

SELECT this_.ServiceId   as ServiceId63_0_, 
     this_.OrganisationTypeId as Organisa2_63_0_, 
     this_.LastUpdated  as LastUpda3_63_0_, 
     this_.LastUpdatedById as LastUpda4_63_0_ 
FROM MyDb.dbo.[ServiceOrganisationType] this_ 
WHERE this_.OrganisationTypeId = 'FirstOrgTypeExample' /* @p0 */ 

在WHERE子句使用枚举的字符串值('FirstOrgTypeExample')而不是long值。我已经试过了标准查询期间铸造OrganisationType到一个长期的,但随后的映射抛出异常说:

NHibernate.QueryException:类型不匹配在 NHibernate.Criterion.SimpleExpression:OrganisationType预计类型 myProduct的。 MyProject.Core.OrganisationType,实际类型System.Int64

任何人都可以帮助我解决问题:如何让NHibernate在生成的sql中使用枚举值?

谢谢

回答

0

OrganisationTypeId是否可以为空?如果是这样,你需要用你的Accept方法来允许这个,否则它将保持为一个字符串值。像下面的东西应该工作。

public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria) 
{ 
    criteria.Expect((x => x.Property.PropertyType.IsEnum && 
      x.Property.PropertyType == typeof(OrganisationType)) || 
      (x.Property.PropertyType.IsGenericType && 
      x.Property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>) && 
      x.Property.PropertyType.GetGenericArguments()[0].IsEnum) 
      ); 
} 
+0

OrganisationTypeId列不可为空,所以我猜这不适用 – Robbie 2012-02-13 00:57:21