我计划使用ASP.NET MVC作为UI层创建3层应用程序,将WCF作为业务层,使用SQL DB作为数据库。
我的业务层将分为服务层(WCF),业务层(业务逻辑,业务模型),数据层(实体框架 - 数据库优先)。
数据层将使用实体框架的实体实现存储库方法,如Get,GetById,Update,Insert。
业务层由业务规则及其模型组成。 (这是在POCO中)。
服务层只会将业务功能公开为可能的服务方法。
MVC中的“M”只是表示模型 - 由Controller使用,以将其转换为JSON / XML并将其提供给View或直接由View使用。
虽然上面提到的方法很常见,但我仍然希望确认这是一个好的设计吗?
我真正的问题是关于层之间的数据传输(UI(MVC) - 服务(WCF) - 业务 - 数据层)
假设我已启动GET操作以从数据库中检索帐户及其特征。在数据库中,它表示为两个不同的表。
在Datalayer中,我想编写一个方法来获取给定的这两个表记录 AccountNumber使用EF。
我的商业模式有两个名为Account和AccountTraits的类。 AccountTraits的对象集合聚合到Account类中。
等
public class Account
{
string AccountNumber;
List<AccountTraits> Traits;
}
现在,如果我想用这些数据填充这些Domain对象,我可以在我的数据层中使用类似下面的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代理对象获取数据并“复制到其演示模型”(它应该有自己的帐户和帐户转移 - 可能有一些额外的字段)?
如果你能对这些主题有所了解,那就太棒了。
谢谢!
答案 0 :(得分:3)
我绝对不会纯粹基于架构使用WCF,除非您特别需要它提供的功能。即某些运输/协助以支持某些企业对企业的需求。 MVC现在具有WebAPI,它基本上与从WCF迁移的内容相同,并且更易于使用,并且可以更轻松地满足您的架构需求。
此外,我甚至不会使用WebAPI,除非我公开了一些我确定会在我的应用程序之外使用的东西。如果此服务层仅由此MVC应用程序使用,那么我将废除它。您仍然可以拥有业务层+数据层,并在没有它的情况下保持关注点的分离。这只是我自己的意见。
通常我会使用View Models,它是为视图量身定制的模型。它们允许我独立地重构View或数据库,只需要更改数据转换代码。即数据库字段更改可能只需要在查询中进行调整,并且ViewModel保持不变,因此使用该视图模型的所有视图保持不变。几乎与您查询和将查询中的实体转换为new Account
的方式相同,只不过我将AccountVM命名为视图模型(模型专门用于视图)
我个人从我的控制器中调用这些类型的数据查询/转换方法。然后控制器将AccountVM或集合传递给View(vm)
,其中vm是持有AccountVM或集合的变量的名称。
这是我从DB获取数据到View的方式。无论如何,EF实体类和VM类通常非常相似,有时相同。我觉得中间业务实体类与其中一个实体类太相似,无法真正保证额外的类和额外的复制。
所以在我看来回答你的几个问题: 1是的,基本上我认为这是一个很好的方法。
2此GetAccountAndItsTraits是从Controller调用的,View是基于您的业务poco(或我称之为ViewModel)。因此,业务层的返回与模型所期望的匹配。我这里没有服务层。但是,我可能会有一些专门用于将EF实体转换为View Models的方法,这将在调用业务模型函数之后发生。换句话说,业务模型将返回EF实体,然后映射函数会将这些实体映射到该情况下所需的任何视图模型,因为您可能有许多使用相同业务方法的View模型和视图。我使用EF Code First,所以我的实体类已经非常接近POCO了,所以它不会冒犯我泄漏到其他层。