5

我有一个模型Enquiry,它可以处于两种状态之一(还有更多,但出于此目的,我只比较两个):NewClosed。查询所处的状态取决于用户能够对查询进行什么操作。例如,无法删除已关闭的查询,而可以删除新的查询等等(基本示例)。

我想坚持这一点,Entity Framework但不知道如何。下面是我的代码。

询问:

public class Enquiry
{
    public int Id { get; set; }
    public string CustomerAccountNumber { get; set; }

    public EnquiryState CurrentState { get; set; }
    public bool CanAddLines { get { return CurrentState.CanAddLines; } }
    public bool CanDelete { get { return CurrentState.CanDelete; } }

    public void ChangeState(EnquiryState currentState)
    {
        CurrentState = currentState;
    }

    public void CloseEnquiry()
    {
        CurrentState.CloseEnquiry();
    }

    /* More methods to change state here */

    public Enquiry()
    {
        CurrentState = new NewEnquiryState(this);
    }
}

查询状态:

public abstract class EnquiryState
{
    internal readonly Enquiry CurrentEnquiry;

    protected EnquiryState(Enquiry currentEnquiry)
    {
        CurrentEnquiry = currentEnquiry;
    }

    public virtual bool CanDelete
    {
        get { return false; }
    }

    public virtual bool CanAddLines
    {
        get { return false; }
    }

    /* More properties here */

    public abstract void CloseEnquiry();

    /* More states here */
}

新查询状态:

public class NewEnquiryState : EnquiryState
{
    public NewEnquiryState(Enquiry enquiry) : base(enquiry) { }

    public override bool CanDelete
    {
        get { return true; }
    }

    public override bool CanAddLines
    {
        get { return true; }
    }

    /* ... */

    public override void CloseEnquiry()
    {
        CurrentEnquiry.ChangeState(new CloseEnquiryState(CurrentEnquiry));
    }

    /* ... */
}

关闭查询状态:

public class CloseEnquiryState : EnquiryState
{
    public CloseEnquiryState(Enquiry enquiry) : base(enquiry) { }

    public override bool CanAddLines
    {
        get { return false; }
    }
    public override bool CanDelete
    {
        get { return false; }
    }

    /* ... */

    public override void CloseEnquiry()
    {
        throw new Exception("Closed Enquiry can't be closed");
    }
}

所以我的问题是,我不确定如何将这些不同的状态存储在数据库中,我是否应该int在每个状态上使用某种字段并Enquiry通过 FK 将它们映射到?另外,我是否也需要将字段映射CanAddLinesCanDelete数据库?看到逻辑包含在状态中,对于状态模式范式来说是全新的

4

1 回答 1

4

您的状态没有任何数据要存储。所以,实际上你只需要存储状态类型:

[NotMapped]
public EnquiryState CurrentState { get; set; }

public int StateType
{
    get 
    {
       // get value based on CurrentState
       return (CurrentState is NewEnquiryState) ? 0 : 1;
    }
    set
    {
        // create EnquireState based on value
        CurrentState = value == 0 ? 
            (EnquiryState)new NewEnquiryState(this) : 
            (EnquiryState)new CloseEnquiryState(this);
    }
}

CanAddLines顺便说一句,如果抽象类虚拟成员已经返回了你需要的东西(例如和CanDelete属性CloseEnquiryState),你不需要覆盖抽象类虚拟成员

于 2013-07-01T12:34:25.223 回答