ASP.NET MVC - 服务层 - 业务层 - 数据层 (EF) - SQL DB :: 数据传输?

Posted

技术标签:

【中文标题】ASP.NET MVC - 服务层 - 业务层 - 数据层 (EF) - SQL DB :: 数据传输?【英文标题】:ASP.NET MVC - Service Layer - Business Layer - Data Layer (EF) - SQL DB :: Data Transfer? 【发布时间】:2012-11-01 14:21:01 【问题描述】:

我打算使用 ASP.NET MVC 作为 UI 层、WCF 作为业务层和 SQL DB 作为数据库来创建 3 层应用程序。

我的业务层将拆分为服务层 (WCF)、业务层(业务逻辑、业务模型)、数据层(实体框架 - 数据库优先)。

数据层将使用实体框架的实体实现存储库方法,例如 Get、GetById、Update、Insert。

业务层由业务规则及其模型组成。 (这是在 POCO 中)。

服务层只是将业务功能公开为可能的服务方法。

MVC 中的“M”只是表示模型 - 由控制器用来将其转换为 JSON/XML 并将其提供给视图或直接由视图使用。

虽然上面提到的方法很常见,但如果这是一个好的设计,我仍然希望得到确认?

我真正的问题是关于层之间的数据传输(UI(MVC)-服务(WCF)-业务-数据层)

假设我启动了一个 GET 操作以从数据库中检索帐户及其特征。在数据库中,它表示为两个不同的表。

帐户 --> 帐户编号、名称、类型 AccountTraits --> Id、AccountNumber、Category 等。

在 Datalayer 中,我想编写一个方法来获取给定的这两个表记录 AccountNumber 使用 EF。

我的业务模型有两个类,称为 Account 和 AccountTraits。 AccountTraits 的对象集合被聚合到 Account 类中。

喜欢,

public class Account

    string AccountNumber;
    List<AccountTraits> Traits;

现在,如果我想用其数据填充这些域对象,我可以在我的数据层中使用如下所示的 EF 查询。

public IEnumerable<Account> GetAccountAndItsTraits(string AccountNumber)

var query = from a in db.Accounts
            select new Accounts() 
            AccountName = a.AccountName,
            Traits = from t in a.AccountTraits
            ....

return query;

    这是从数据层 (EF) 填充业务模型 POCO 的常规方法吗?

    现在,在应用了一些业务逻辑之后,我想将这些集合返回到 UI。我如何将这些转移到服务层以及如何将其提供给 UI 模型?

    我是否必须在 WCF 中将 DataContract 定义为准确的类定义作为业务模型,然后 “复制数据” 给它并提供给 UI ?然后 UI 应该从 WCF 代理对象中获取数据并“复制到它的 Presentation Model”(这又应该有自己的 Accounts 和 AccountTraits - 可能带有一些额外的字段)?

如果您能对这些主题有所启发,那就太好了。

谢谢!

【问题讨论】:

这对于新应用程序来说似乎很复杂。 这是一个好方法。我也遇到了同样的问题。在我对它的研究中,我发现,我们可以在表示层和 wcf 之间使用 datacontract。看来您在 Datalayer 中提取数据库结果的操作是正确的。 【参考方案1】:

我绝对不会纯粹基于架构来使用 WCF,除非您特别需要它提供的功能。 IE。某些传输/协议以支持某些业务对业务的需求。 MVC 现在有了 WebAPI,它基本上与从 WCF 迁移的东西相同,并且更易于使用,并且可能会更轻松地满足您的架构需求。

此外,我什至不会使用 WebAPI,除非我公开了一个我知道肯定会在我的应用程序之外使用的东西。如果这个服务层只会被这个 MVC 应用程序使用,那么我会取消它。您仍然可以拥有业务层 + 数据层并在没有它的情况下保持关注点分离。这只是我个人的看法。

通常我使用视图模型,它们是为视图量身定制的模型。它们允许我独立地重构视图或数据库,并且只需要更改数据转换代码。 IE。更改的数据库字段可能只需要在查询中进行调整,并且 ViewModel 保持不变,因此使用该视图模型的所有视图都保持不变。与查询实体并将其转换为new Account 的方式几乎相同,只是我将我的 AccountVM 命名为视图模型(model 专门用于 view

我个人从我的控制器中调用这些类型的数据查询/转换方法。然后控制器将 AccountVM 或集合传递给 View(vm),其中 vm 是保存 AccountVM 或集合的变量的名称。

这就是我将数据从 DB 获取到 View 的方式。无论如何,EF 实体类和 VM 类通常非常相似,有时甚至完全相同。我觉得中间业务实体类与一个或另一个过于相似,无法真正保证额外的类和额外的复制。

所以在我看来回答你的几个问题: 1 是的,基本上我认为这是一个很好的方法。

2 这个 GetAccountAndItsTraits 是从 Controller 调用的,而 View 是基于您的业务 poco(或者我称之为 ViewModel)的。因此,业务层的回报与您的模型所期望的相符。我不会在这里有服务层。但是,我可能有一些专门用于将 EF 实体转换为视图模型的方法,这将在调用业务模型函数之后发生。换句话说,业务模型将返回 EF 实体,然后映射函数将这些实体映射到这种情况下所需的任何视图模型,因为您可以拥有许多使用相同业务方法的视图模型和视图。我使用 EF Code First,所以我的实体类已经非常接近 POCO,所以它们泄漏到其他层并不会冒犯我。

【讨论】:

这本质上也是我使用的方法。我要补充一点,Automapper 完成了将 EF 实体映射到 ViewModel 的大量工作。 是的,我打算这样做,但 AutoMapper 可能会令人生畏。我可能会暂时不使用并感受一下其他所有内容,然后逐渐开始使用 AutoMapper。 @AaronLS 感谢您的回复。我必须使用 WCF 是因为我的业务层位于单独的物理框中。我使用 WebAPI 在视图(客户端浏览器)与 UI 服务器(控制器)之间进行通信,并且来自 UI 服务器的控制器必须调用 WCF 才能访问业务服务。我需要将业务逻辑应用于业务层中的业务模型,而不是 ViewModel。 那么你的服务会暴露与你的业务层同名的方法,因为它实际上只是一个代理来启用跨服务器通信。我对 WCF 中如何处理复杂类型的了解不够,无法就您有关数据合同的问题提供具体建议。如果您为您的服务使用 WebAPI 而不是 WCF,我相信您将拥有一个包含您的业务 poco 类的项目,并且该项目被您的 MVC 项目和您的 Web 服务项目引用。这种方式都可以理解从 WebAPI 返回到 Controller 的类型。 @Karthik 我要补充一点,使用 WebAPI 在客户端浏览器和服务器之间进行通信并不常见(您在原始问题中问过这种方法是否常见):“我使用 WebAPI 在视图之间进行通信(客户端浏览器)到 UI 服务器(控制器)”。浏览器调用 WebAPI 的场景通常涉及请求 XML/Json 以支持 ajax 请求或向某些 jquery 组件(如许多 jquery 网格)提供数据。所以确实会发生,但是服务器/浏览器之间的大部分通信都是针对 MVC 操作的。

以上是关于ASP.NET MVC - 服务层 - 业务层 - 数据层 (EF) - SQL DB :: 数据传输?的主要内容,如果未能解决你的问题,请参考以下文章

csharp asp.net mvc业务层实现

asp.net mvc 怎样搭建业务逻辑层比较好?

MVC(ASP.NET MVC)带3层架构如何协同工作?

asp.net中的三层架构是啥意思

在具有 3 层架构的 ASP.NET MVC 应用程序中验证业务规则的更好方法是啥?

ASP.NET中MVC的理解