2012-02-12 4 views
3

TransactionException은을 CheckNotZombied : 처리가 연결되지 않았거나 끊어]와 NHibernate.Transaction.AdoTransaction.CheckNotZombied() 108
NHibernate.Transaction.AdoTransaction.Rollback() 144유창함 NHibernate에 열거 매핑

는 다음과 같은 방법으로 조회 할 자 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 :

,691 :

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합니다. 그래서 내 Accept 메서드는 다음과 같습니다.

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 : 오류 BIGINT 데이터 유형은 nvarchar 변환"- ServiceOrganisationType 테이블 쿼리 동안 NHib 다음 SQL을 생성하는 것이 다음에서

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 절은 길이가 값 대신 enum ('FirstOrgTypeExample')에 대한 문자열 값을 사용합니다. 내가 기준 쿼리 동안 긴에 OrganisationType을 캐스팅하려했지만, 다음 매핑 예외가 말을 발생합니다 :

NHibernate.QueryException : 형식 불일치를 NHibernate.Criterion.SimpleExpression에 : OrganisationType 예상 유형을 MyProduct합니다. MyProject.Core.OrganisationType, 실제 형식 System.Int64

아무도 내가 어떻게 생성 된 SQL에서 열거 형 값을 사용하여 NHibernate를 얻을 수있는 운동을 도와 드릴까요?

감사합니다.

답변

0

OrganisationTypeId는 null 가능합니까? 그렇다면 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 열에 nullable이 없으므로 적용되지 않습니다. – Robbie