使用 WCF/OData 作为访问层而不是直接使用 EF/L2S/nHibernate 的论点

Posted

技术标签:

【中文标题】使用 WCF/OData 作为访问层而不是直接使用 EF/L2S/nHibernate 的论点【英文标题】:Arguments of using WCF/OData as access layer instead of EF/L2S/nHibernate directly 【发布时间】:2011-01-30 17:24:27 【问题描述】:

我们主要开发低流量但高度专业化的网络应用程序。通常我们使用 L2S、EF 或 nHibernate 作为访问层,然后向其抛出 Asp.Net MVC,其中对于正常的 crud 操作,我们直接查询 ISession/DataContext,但对于更高级的功能/副作用,我们将其放在某种服务层。

现在,我正在考虑通过 OData(WCF 数据服务)发布数据并从控制器(或者当一个好的模板引擎出现时甚至从 jQuery)查询数据,并通过 WCF 服务(或作为 WCF 数据服务上的自定义方法?)。这种架构有什么优点/缺点?

除了更高的复杂性和延迟之外,我还有什么收获吗?更好地分离关注点(或者这只是一种错觉)?

编辑: 用例如创建一个完整的 ajax 驱动解决方案是个好主意吗? WCF RIA Services?还是松了太多的灵活性?感觉就像您可以完全从您的逻辑中调度您的视图,哎呀,应该能够只编写纯 html,甚至不需要 asp.net MVC?但我想有很多新的问题出现了?

【问题讨论】:

【参考方案1】:

不要这样做。对不起,但这是一种愚蠢的过度设计的方法。您在一个进程中,并且坚持运行网络连接并将所有传递的数据编码为 XML 并返回,再加上在查询语义有限的 HTTP 连接上运行它?不要告诉任何人你试过了。

关注点分离在这里是一种错觉——您将高度优化的领域模型替换为简化的数据层。

那说:我喜欢 OData - 太棒了。但它不是一种程序内技术,它是一种前端技术,如 ASP.NET MVC - 只是不针对最终用户,而是针对集成到您的数据中的另一个程序。它应该在类似的场景中使用,并且在通过信任边界暴露数据时(例如,Silverlight 是一个信任边界,因为请求可以被伪造)。

它没有针对替换进程中的高端应用程序运行时层(如 NHibernate)进行优化。

【讨论】:

+5 如果可以的话。 OData 是一种简单的方式,可以轻松地公开数据以供其他人访问,而不是为您自己的应用程序。 啊哈,...所以我并不孤单 :-) 为什么这家伙有 1 个代表 感谢对相关问题的反馈***.com/questions/14769120/…【参考方案2】:

正如 TomTom 所述,您不想在流程中为 OData 支付环回成本。如果您可以直接看到您的数据库并且它是您自己的应用程序的数据库,那么没有理由将 WCF 数据服务放在中间。我将继续使用您提到的其他选项之一(L2S、EF、nHibernate)。

现在,如果您需要通过 http 端点公开数据以供其他应用程序使用,或者甚至为您自己的应用程序(如果客户端中有一些需要从服务器访问数据的 jQuery 代码),那么绝对是 OData 端点可能会有所帮助,而 WCF 数据服务是创建数据服务的最简单方法。

【讨论】:

感谢对相关问题的反馈***.com/questions/14769120/…【参考方案3】:

TomTom 有很多选票,虽然他没有错,但他也不对,尽管他的语气很有说服力。

在这种特殊情况下,OP 似乎正在编写一个 Intranet LOB 风格的应用程序,该应用程序可能只会受到模仿底层数据库的 OData 服务的阻碍,但如果他没有模仿底层数据库怎么办?

如果他正在基于各种或未知的未来数据源构建应用程序,那么服务层可以统一、重新呈现、简化和聚合这些服务,即使大部分查询最终返回到 SQL Server 中的 SQL Server。隔壁房间。

同样,如果您要构建大规模应用程序,我所说的规模是指数百万用户希望在操作之间等待几秒钟,而不是每小时进行数百万次外汇交易,那么在您的应用程序之间放置一个服务层数据是一种常见的模式。互联网的可扩展性基于许多小型无状态 HTTP 服务器和介于两者之间的缓存基础设施。

在现实生活中,相同的查询会运行无数次,人们会一遍又一遍地刷新页面或点击相同的链接。没有人真正要求 10m 行,因为没有多少人可以一口气看到它。因此,在小页面中工作可以保持数据流动和请求交错。您还有机会在服务层中引入共享的 RAM 缓存,甚至是 RAM 数据库。

您甚至可能会发现需要对数据库进行分片或在 SQL 和键/值存储之间进行分区。然后,您可以在中间层进行连接、横向扩展,并将连接和计算密集型的东西从数据库服务器上卸载。

互联网规模的规则是,数据库是您的热点,您需要尽一切可能阻止任何人与之交谈!无论是 iPad、ISP 代理、IIS 输出缓存还是 Redis 缓存中的本地 HTTP 缓存,所有这些层都有助于分散负载,减轻负担。

所以如果 Carl 来采访我并告诉我他考虑在他的 SQL 框之前放置一个 OData 层,我很想听听他的推理。

【讨论】:

【参考方案4】:

WCF 数据服务和 OData 支持 JSON,因此您可以利用它来最小化负载。此外,使用 WCF 数据服务,您可以完全控制您的数据访问。您不必滚动实体框架。您可以自定义所有内容。好处是使用 WCF 数据服务和 OData 完全为您处理协议结构。从 MVC 消费服务是一个添加服务引用。 WCF 数据服务在 WCF 上运行,因此您可以执行 OData 类型交付之外的其他 Web 服务,因此非常灵活。

OData 的性质以及 WCF 数据服务处理 OData 的方式都存在一些限制,但它们是相当具体的,如果它们出现在您的体系结构中,有办法绕过它们。

如果您的解决方案与单个 Web 应用程序隔离,那么将数据层嵌入到该应用程序中效果很好。但是,如果您有任何需要让另一个应用程序或流程访问数据层或共享业务逻辑,那么探索将数据层放入 WCF 数据服务的选项是非常值得的。例如,您可以编写一个 PowerShell 脚本,用 2 行代码调用 Web 服务方法。因此,如果您有希望能够从 Web 应用程序以及命令行或计划任务运行的域逻辑,那么您的 WCF 数据服务层可以为所有人处理该场景,而无需复制逻辑或代码。

给猫剥皮的方法有很多。我在业务应用程序中使用了这两种方法,并且不会说应该避免其中一种。它们都运行良好,并提供大量价值而不会造成损害。

【讨论】:

【参考方案5】:

公平地说,这种方法的好处可能超过了性能问题,而性能问题无疑是巨大的。与进程内解决方案相比,以这种方式构建的应用程序的延迟将增加几个数量级,并且执行计算资源的成本可能高出数倍。

话虽如此,在人力资源有限的开发场景中,这可能会更好。它允许承包商快速被聘用,以便以适合他们的任何语言非常快速地编写新屏幕或全新应用程序。与专有的本土解决方案相比,开发人员可以更快地上手。配置文件中不再有 sa 密码,如果需要,注入自定义安全层,统一日志记录和审计,将多个数据存储组合到一个一致的资源中。如果你有一个异构平台,你不需要编写 SDK,它们已经用许多重要的语言编写了。 oData 与 MS Excel 配合得非常好,这在许多组织中是一个巨大的胜利。根据您的网络拓扑,如果您在远程办公室或防火墙后面(例如,在进行演示的客户端站点),通过 Internet 路由可能比使用租用线路更便宜甚至更快.

对于大型数据集,请求和打包的开销变得不那么重要。例如,对于报告场景。虽然我从未设计过这样的东西,但我可以根据您的企业文化和可用资源了解在内部使用 oData 端点可能有用的地方。

【讨论】:

在我的世界里,人们会因为利用这些优势而被解雇。为什么?因为与维护成本相比,开发成本无关紧要。雇用开发人员使用适合特定开发人员的任何语言都是维护的噩梦,即使在 ddevelopment 期间也是如此,更糟糕的是 2 年后。保持对技术堆栈的控制和精简,否则您最终会寻找一个会说 10 语言非常好的人来进行 xcross 模块维护。抱歉,对于大型数据集,过度读取甚至更糟。尝试在 odata 上获取 1000 万行。我一直这样做。 你的世界听起来很糟糕,你有我的同情@TomTom。

以上是关于使用 WCF/OData 作为访问层而不是直接使用 EF/L2S/nHibernate 的论点的主要内容,如果未能解决你的问题,请参考以下文章

在数据层而不是单层应用程序中进行审计

为啥不使用 Flatten 后跟 Dense 层而不是 TimeDistributed?

如何使用 HitTest 获得最前面的层而不是最深层

将授权放在服务层而不是 Web API 层

如何显示预训练模型的层而不是 model.summary() 输出中的单个条目?

对具有直接关系但在细节层而非维度层的事实表进行建模