c# - 使用 Entity Framework 持久化状态模式

标签 c# entity-framework ef-code-first unit-of-work state-pattern

我目前正在使用 MVC 3 开发一个项目。我已经分离了我的关注点,所以有诸如核心、存储库、UI、服务等项目。我已经实现了存储库、UnitOfWork 和最重要的状态模式。

我正在使用 Entity Framework 4.3 来保存我的数据,但我遇到了一个相当烦人的情况,涉及到当前状态的持久化。以下是一些类示例:

public class Request
{
    public int RequestId { get; set; }

    public State CurrentState { get; set; }
}

public abstract class State
{
    [Key]
    public string Name {get; set;}

    public virtual void OpenRequest(Request request)
    {}

    public virtual void CloseRequest(Request request)
    {}
}

public class RequestIsOpenState : State
{
    public RequestIsOpenState()
    {
        this.Name = "Open";
    }

    public override void CloseRequest(Request request)
    {
        request.CurrentState = new RequstIsClosedState();
    }
}

public class RequestIsClosedState : State
{
    public RequestIsClosedState()
    {
        this.Name = "Closed";
    }

    public override void OpenRequest(Request request)
    {
        request.CurrentState = new RequstIsOpenState();
    }
}

使用上面的示例,我会得到一个主键冲突异常,因为它试图在 States 表中创建一个新状态。

因为状态更改是在域层内完成的,所以我不能只是从存储库中“获取”状态并通过执行以下操作使用外键设置它:

Request request = unitOfWork.RequestRepository.Find(1);
request.CurrentState = unitOfWork.StateRepository.Find("Closed");

我知道我可以选择不映射状态属性,并在请求类中保留一个字符串属性,然后在实体被水合时通过工厂在获取和设置时来回转换它们(参见 this answer ).

我想要做的就是持久化状态类,因此当返回请求时,我可以立即访问状态方法,而不会为了处理一个持久性问题而让大量 EF 东西污染我的域层。另一个好处是它给我带来了额外的好处,即在 SQL 中有一个表来查询已知状态。

最佳答案

我认为您可以通过缓存只创建一次的 State 实例来改进它,以避免每次都创建列表并避免 foreach:

public static class StateFactory
{
    private static Dictionary<string, State> statesCache = FindAllDerivedStates();

    public static State GetState(string stateTypeName)
    {
        return statesCache[stateTypeName];
    }

    private static Dictionary<string, State> FindAllDerivedStates()
    {
        var derivedType = typeof(State);
        var assembly = Assembly.GetAssembly(typeof(State));
        return assembly.GetTypes().Where(t => t != derivedType && derivedType.IsAssignableFrom(t))
                    .Select(t => (State)Activator.CreateInstance(t))
                    .ToDictionary(k => k.Name);
    }
}

关于c# - 使用 Entity Framework 持久化状态模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21784457/

相关文章:

.net - 十进制作为主键在 Dev (Win7/64bit) 中有效,但在生产中无效 (Win2008R2/64bit) 公共(public)语言运行时检测到无效程序

entity-framework - Entity Framework 代码优先和存储过程

c# - 在 SaveDialog 中强制扩展

c# - 如何将 XML 文件上传到 TomCat?

c# - Entity Framework 不可为空的列映射到可为空的实体属性

entity-framework - 不同项目中的Entity Framework 5和Visual Studio 2012 POCO类

VS2005 中的 C# : what do the following types default to in C#?

C# 在缓存中存储值类型

c# - 如何使用 asp.net 实体数据模型将选定的下拉列表值插入数据库

.net - 第一个代码 : Database only created after execute certain code?