我需要一些帮助来为我的应用程序做出设计选择。这是一个相当简单的Web应用程序,绝对不是企业级或企业级的。
该体系结构是标准的MVC 5 / EF 6 / C#ASP.NET,页面与SQL Server中的后端数据库通信,并且所有表都具有使用EF设计器从VS 2013生成的相应实体对象我不认为在不久的将来会随时改变。因此,创建超级抽象“如果我的数据库发生变化”等分离可能毫无意义。 我是一个单人操作,所以我们不会说大型团队等。
我想要的是使用DbContext和LINQ操作在我的数据库上进行CRUD和查询操作的简洁方法 - 但我不擅长数据库相关的代码设计。这是我的方法
1。带有方法的静态类 - 我应该创建一个静态类(我的DAL)来保存我的datacontext,然后提供控制器可以直接调用的函数
e.g. MyStaticDBLib.GetCustomerById(id)
但是当我们尝试从断开连接的实例更新记录时,这会产生问题(即我创建了一个来自JSON响应并需要'更新'我的表的对象)。好处是我可以将我的操作集中在Lib或DAL文件中。这也很快变得复杂和混乱,因为我不能为每个场景创建方法,所以我最终在我的控制器中使用了一些LINQ代码,以及这些LIB方法处理的位
2。具有上下文的类,以单例形式保存,并从控制器调用
MyContext _cx = MyStaticDBLib.GetMyContext(“sessionKey”);
var xx = cx.MyTable.Find(id) ; //and other LINQ operations
由于我的数据查询代码现在在我的控制器中,但感觉有点乱,但至少我有每个会话的干净上下文。另一个想法是LINQ-to-SQL已经在某种程度上抽象了数据层,只要实体保持不变(实际存储可以改变),那么为什么不这样做呢?
第3。使用通用存储库和单元工作模式 - 现在我们变得更加花哨。我已经阅读了一些关于这种模式的内容,并且有很多不同的建议,包括一些强烈建议EF6已经将存储库构建到其上下文中,因此这有点过分等等。它确实感觉有点过头但需要有人在这里告诉我,鉴于我的上下文
4。别的什么?其他一些处理基本数据库/ CRUD的简洁方法
现在我有了库类型方法(上面的1.),而且它变得越来越混乱。我已经阅读了很多文章而我正在挣扎,因为有很多不同的方法,但我希望我所提供的背景可以引出一些回答,说明哪种方法可能适合我。我需要保持简单,并且我将在不久的将来进行单人操作。
答案 0 :(得分:1)
绝对不是#1。上下文不是线程安全的,你当然不希望它作为静态类中的静态var。您只是要求您的应用程序爆炸。
只要您确保您的单件是线程安全的,选项2是可行的。换句话说,它是每个线程的单例,而不是整个应用程序。否则,适用#1的相同问题。
选项3是典型但短视的。工作模式的存储库/单元几乎被ORM取代。在这样的另一层中包装实体框架只会消除使用Entity Framework的许多好处,同时增加开发应用程序所涉及的摩擦。换句话说,它是双输的,完全没必要。
所以,我会选择#4。如果应用程序足够简单,只需直接使用您的上下文。使用DI容器将您的上下文注入控制器并使其成为请求范围(每个请求的新上下文)。如果应用程序变得更复杂,或者您真的非常关心依赖实体框架,那么应用服务模式,您可以在其中公开应用程序所需的特定数据集的端点。将您的上下文注入服务类,然后将您的服务注入控制器。提示:您的服务端点应返回已从数据库中完全查询的完整数据(即返回列表和类似的枚举,而不是可查询的数据)。
答案 1 :(得分:0)
虽然Chris的回答是一种有效的方法,但另一种选择是使用一个非常简单的具体存储库/服务外观。这是您将所有数据访问代码放在接口层之后的地方,例如IUserRepository.GetUsers(),然后在此代码中您拥有所有实体框架代码。
这里的值是关注点的分离,增加了可测试性(尽管EF6 +现在允许直接进行模拟,因此这不是问题),更重要的是,如果您决定有一天更改数据库代码,它们都在一个地方......没有大量的开销。
通过依赖注入注入也是一件轻而易举的事。