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))),),)]