2017-09-29 1 views
0

우리의 어플리케이션에서 우리는 엔티티 패턴을 사용하고 있습니다. 상태를 데이터베이스 값에 매핑하는 데 문제가 있습니다. 우리의 현재 솔루션은 작동하지만 IQueryable (최대 절전 모드에서)을 지원하지 않으므로 리포지토리에서 .ToList()를 호출해야합니다.NHibernate와 FluentMapping을 사용하는 상태 패턴

public class Gap 
{ 
    [ommited] 

    public virtual IGapState State { get; protected set; } 
    public virtual IGapState PreviousState { get; protected set; } 
} 

는 현재 IGapState에 대한 우리의 매핑은 다음과 같습니다 : 여기

는 우리의 실체

public class GapMap : ClassMap<Gap> { 
    [ommited] 

    Map(x => x.State).CustomType<GapStateType>(); 
    Map(x => x.PreviousState).CustomType<GapPreviousStateType>() 
} 

그리고 이에 대한 우리의 사용자 정의 유형은 다음과 같습니다

public class GapStateType : ICompositeUserType 
{ 
    public bool IsMutable => false; 
    public virtual string[] PropertyNames => new string[1] { "State" }; 
    public IType[] PropertyTypes => new IType[1] { NHibernateUtil.Int32 }; 
    public Type ReturnedClass => typeof(IGapState); 
    public object Assemble(object cached, ISessionImplementor session, object owner) => cached; 
    public object DeepCopy(object value) => value; 
    public object Disassemble(object value, ISessionImplementor session) => value; 
    public new bool Equals(object x, object y) => object.Equals(x, y); 
    public int GetHashCode(object x) => x.GetHashCode(); 
    public object GetPropertyValue(object component, int property) 
    { 
     IGapState state = (IGapState)component; 
     return state.Discriminator; 
    } 

    public object NullSafeGet(IDataReader dr, string[] names, ISessionImplementor session, object owner) 
    { 
     State state = (State)NHibernateUtil.Int32.NullSafeGet(dr, names[0]); 
     switch (state) 
     { 
      case State.New: 
       return new New(); 
      case State.InProgress: 
       return new InProgress(); 
      case State.TicketClosedWaitingForEvidence: 
       return new TicketClosedWaitingForEvidence(); 
      case State.EvidenceProvidedWaitingForTicketClosure: 
       return new EvidenceProvidedWaitingForTicketClosure(); 
      case State.EvidenceProvidedWaitingForTicketAssigment: 
       return new EvidenceProvidedWaitingForTicketAssigment(); 
      case State.FalsePositiveWaitingForApproval: 
       return new FalsePositiveWaitingForApproval(); 
      case State.FalsePositiveApproved: 
       return new FalsePositiveApproved(); 
      case State.RiskStateWaitingForApproval: 
       return new RiskStateWaitingForApproval(); 
      case State.RiskStateApproved: 
       return new RiskStateApproved(); 
      case State.Closed: 
       return new Closed(); 
      default: 
       return new Null(); 
     } 
    } 

    public void NullSafeSet(IDbCommand cmd, object value, int index, bool[] settable, ISessionImplementor session) 
    { 
     //State state = (State)value; 
     //NHibernateUtil.Int32.NullSafeSet(cmd, (int)state, index); 
     IGapState state = (IGapState)value; 
     NHibernateUtil.Int32.NullSafeSet(cmd, (int)state.Discriminator, index); 
    } 

    public object Replace(object original, object target, ISessionImplementor session, object owner) 
    { 
     return target; 
    } 

    public void SetPropertyValue(object component, int property, object value) 
    { 
     throw new InvalidOperationException("Discriminator is an immutable object. SetPropertyValue isn't supported."); 
    } 
} 

Google에서 호출하는 보관소에

public IEnumerable<Gap> FindWatingForApprovalRisk() 
{ 
    return FindAll().ToList().Where(x => x.State.Discriminator == State.RiskStateWaitingForApproval); 
} 

많은 양의 항목이 없을 때까지 괜찮습니다. 우리가 된 IQueryable에 ToList() 변경 반환 형식을 잘라 때 우리는 다음과 같은 예외를 얻을 :

could not resolve property: State.Discriminator of: 
Exprimo.CBA.Model.Entities.GapPortal.Gap 
[.Count[Exprimo.CBA.Model.Entities.GapPortal.Gap] 
(.Where[Exprimo.CBA.Model.Entities.GapPortal.Gap] 
(NHibernate.Linq.NhQueryable`1[Exprimo.CBA.Model.Entities.GapPortal.Gap], 
Quote((x,) => (Equal(Convert(x.State.Discriminator), p1))),),)] 

답변

0

NHibernate에이 x.State.Discriminator으로 무엇을 해야할지하지 않습니다, 당신의 매핑이 x.State에 정차하기 때문이다.

시도 :

.Where(x => x.State == new RiskStateWaitingForApproval())