在我们的应用中,我们正在为我们的实体使用状态模式。我们遇到了一个问题,即将状态映射到数据库值。我们当前的解决方案有效,但不支持IQueryable(来自hibernate),因此迫使我们在存储库中调用.ToList()。
这是我们的实体:
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.");
}
}
在存储库中我们调用
public IEnumerable<Gap> FindWatingForApprovalRisk()
{
return FindAll().ToList().Where(x => x.State.Discriminator == State.RiskStateWaitingForApproval);
}
在我们没有大量实体之前,这一切都很好。当我们切出ToList()并将返回类型更改为IQueryable时,我们得到以下异常:
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 :(得分:0)
NHibernate不知道如何处理x.State.Discriminator,因为你的映射在x.State停止。
尝试:
.Where(x => x.State == new RiskStateWaitingForApproval())