在MVC中在应用程序级别持久化数据库存储的查找数据的最佳实践



在MVC+EF中缓慢前行,并努力专注于以正确的方式做事。现在我想在表单中添加一个下拉列表,但我想避免每次加载页面时都会访问数据库,所以我想将数据存储在应用程序级别。我认为创建应用程序级变量不是最好的方法。我读过关于使用缓存和静态实用程序函数的文章,但令人惊讶的是,没有什么听起来非常明确。(静态类不适合单元测试,缓存不适合

所以我有两种情况很好奇,我不确定两者的方法是否会有所不同。

1) 一个基本的查找,比方说五十个州。小,有定义,永远不会改变。应用程序启动时加载。(不是在寻找硬编码的解决方案,而是从数据库中检索。)

2) 查找很少会改变,只能通过类似管理员的屏幕进行。比方说,你的产品销售的城市/商店。因此数据将被存储在模型中,但将是相对静态的,除非有人通过应用程序进行更改。因此,不希望每次需要填充下拉列表/列表框时都访问数据库。

看起来像是基本的东西,但它基本上与这个从未被回答的话题相同:

在MVC应用程序中使用静态EF对象上下文以获得更好的性能好吗?

感谢您的帮助。

我将分几个部分回答您的问题。首先,在MVC中使用静态变量或缓存模式本身就不好吗。答案是否定的。只要你的体系结构支持它们就可以了。只要把你的缓存放在正确的位置,并设计可测试性,我稍后会解释。

第二部分是存储这种类型的持久化数据的"正确"方法,这样您就不必往返于DB来填充常见的UI项。为此,我不建议存储EF对象。我会创建您缓存的POCO对象(查看模型或类似对象)。因此,在你的50个州的例子中,你可能会有这样的东西:

public class State
{
    public string Abbreviation { get; set; }
    public string Name { get; set; }
}

然后你可以这样做来创建你的缓存列表:

List<State> states = Context.StateData.Select(s => new State { Abbreviation = s.Abbreviation, Name = s.Name}).ToList();

最后,无论您的缓存解决方案是什么,它都应该实现一个接口,以便您可以模拟该缓存方法进行测试。

要做到这一点,而不需要运行到循环引用或使用反射,您将需要至少3个程序集:

您的MVC应用程序用于定义POCO对象和接口的类库类库确实可以执行数据访问和缓存(如果这样更容易维护和/或测试的话,显然可以将其拆分为两个库)

这样你就可以在MVC代码中有这样的东西:

ICache myCache = CacheFactory.CreateCache();
List<State> states = myCache.ListStates();
// populate your view model with states

ICache和State在一个库中,而ICache的实际实现在另一个库。

这就是我为我的标准体系结构所做的:将数据访问无关的POCO对象和接口与数据访问分离到一个单独的库中,数据访问与我的MVC应用程序分离。

研究使用依赖注入工具,如unity、ninject、structuremap等。这些工具将通过实现一个内核来实现您想要的应用程序级控制,该内核以与您所描述的非常相似的方式保持对象。

最新更新