使用 WCF/OData 作为访问层而不是直接使用 EF/L2S/nHibernate 的争论
我们主要开发低流量但高度专业化的 Web 应用程序。通常我们使用 L2S、EF 或 nHibernate 作为访问层,然后将 Asp.Net MVC 扔给它,对于正常的增删改查操作,我们直接查询 ISession/DataContext,但对于更高级的功能/副作用,我们将其放在某种形式中服务层。
现在,我正在考虑通过 OData(WCF 数据服务)发布数据,并从控制器(甚至在出现良好模板引擎时从 jQuery)查询数据,并通过 WCF 服务(或作为自定义方法)发布服务操作在 WCF 数据服务上?)。这种架构有什么优点/缺点?
除了更高的复杂性和延迟之外,我还能获得其他好处吗?更好的关注点分离(或者这只是一种幻觉)?
编辑: 使用例如创建完整的ajax驱动解决方案是个好主意吗? WCF RIA 服务?或者是否失去了太多的灵活性?感觉你可以完全从逻辑中分派你的视图,那么,哎呀,人们应该能够只编写纯 HTML,甚至不需要 ASP.NET MVC?但我想会出现很多新问题吗?
We develop mostly low traffic but highly specialized web applications. Normally we use L2S, EF or nHibernate as access layer and then throws Asp.Net MVC to it and in which for normal crud operations we query the ISession/DataContext directly but for more advanced functions/side effects we put it in a some kind of service layer.
Now, i was think about publishing the data through OData (WCF Data Service) and query that from the controllers (or even from jQuery when the a good template engine shows up) and publish the service operations through a WCF service (or as custom methods on the WCF Data Service?). What advantages/disadvantages does this architecture poses?
Do I gain something except higher complexity and latency? Better separations of concerns (or is it just a illusion)?
Edit:
Can it be a good idea to create a complete ajax driven solution with eg. WCF RIA Services? Or do one loose too much flexibility? Feels like you can completely dispatch your views from your logic then, heck, one should be able to just write pure HTML, not even a asp.net MVC should be needed? but i guess there's a lot of new problems arising?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不要这样做。抱歉,这是一种愚蠢的过度设计方法。您处于一个进程中,并且坚持运行网络连接并将所有传递的数据编码为 XML 并返回,再加上通过具有有限查询语义的 HTTP 连接运行它?不要告诉任何人你尝试过。
关注点分离在这里是一种幻觉——您用简化的数据层替换高度优化的域模型。
也就是说:我喜欢 OData - 太棒了。但它不是程序内技术,而是前端技术,如 ASP.NET MVC - 只是不适合最终用户,而是让另一个程序集成到您的数据中。它应该用在类似的场景中,以及在跨信任边界公开数据时(例如,Silverlight 是一个信任边界,因为请求可以伪造)。
它没有经过优化来替换进程中的高端应用程序运行时层(例如 NHibernate)。
Don't Do it. Sorry, but this is a stupid over-engineered approach. You are IN ONE PROCESS and you insist on running a network connection AND coding all passing data into XML and back out, plus running it over a HTTP connection with limited query semantics? Don't tell anyone you even tried.
Separation of concern is an illusion here - you replace a highly optimized domain model with a simplified data layer.
THAT SAID: I love OData - great. But it is not an in program technology, it is a FRONT END technology, like ASP.NET MVC - just not for the end user, but for ANOTHER program to integrate into your data. It should be used in similar scenarios, and when exposing data over trust borders (Silverlight - for example - is a trust border as the requests can be faked).
It is NOT optimized to replace in process high end application run-time layers like NHibernate.
正如 TomTom 提到的,您不想在流程中为 OData 支付环回成本。如果您可以直接访问数据库并且它是您自己的应用程序的数据库,那么没有理由将 WCF 数据服务放在中间。我将继续使用您提到的其他选项之一(L2S、EF、nHibernate)。
现在,如果您需要通过 http 端点公开数据以供其他应用程序使用,甚至是您自己的应用程序(如果客户端中有一些需要从服务器访问数据的 jQuery 代码),那么 OData 端点肯定会有所帮助,并且WCF 数据服务是最简单的创建方法。
As TomTom mentions, you don't want to pay the cost of loopback for OData when within a process. If you have direct line-of-sight to your database and it's your own application's database, then there is no reason to put WCF Data Services in the middle. I would continue to use one of the other options you mentioned (L2S, EF, nHibernate).
Now, if you need to expose data over your http endpoint for other applications to consume, or even for your own application if you have some jQuery code in the client that needs to access data from the server, then definitely an OData endpoint may help and WCF Data Services is the simplest way to create one.
TomTom 有很多选票,虽然他没有错,但他也有不对的地方,尽管他的语气很有说服力。
在这个特殊的实例中,OP 似乎正在编写一个 Intranet LOB 样式的应用程序,该应用程序可能只会受到模仿底层数据库的 OData 服务的阻碍,但如果他没有模仿底层数据库怎么办?
如果他正在基于各种或未知的未来数据源构建应用程序,那么服务层可以统一、重新呈现、简化和聚合这些服务,即使大部分查询最终返回到隔壁房间的 SQL Server。
同样,如果您正在构建大规模的应用程序,我所说的规模是指数百万用户希望在操作之间等待几秒钟,而不是每小时数百万笔外汇交易,那么在您的应用程序之间放置一个服务层,数据就是常见模式。互联网的可扩展性基于许多小型无状态 HTTP 服务器以及其间的缓存基础设施。
在现实生活中,相同的查询会运行无数次,人们会一遍又一遍地刷新页面或单击相同的链接。没有人真正要求 10m 行,因为没有多少人能够一次性看完它。因此,在小页面中工作可以保持数据流动并请求交错。您还有机会在服务层中引入共享 RAM 缓存,甚至是 RAM 数据库。
您甚至可能发现需要对数据库进行分片或在 SQL 和键/值存储之间进行分区。然后,您可以在中间层进行联接、横向扩展,并将联接和计算密集型内容从数据库服务器上卸载。
互联网规模的规则是数据库是您的热点,您需要尽一切努力防止任何人与其交谈!无论是 iPad 中的本地 HTTP 缓存、ISP 代理中的本地 HTTP 缓存、IIS 输出缓存中的本地 HTTP 缓存,还是 Redis 缓存中的本地 HTTP 缓存,所有这些层都有助于分散负载、减轻负担。
因此,如果 Carl 来面试我并告诉我他考虑在他的 SQL 框之前放置一个 OData 层,我很有兴趣听听他的推理。
TomTom has a lot of votes and although he's not wrong, he's also not right, in spite of his persuasive tone.
In this particularly instance, the OP appears to be writing an intranet LOB style app that probably only stands to be impeded by an OData service mimicking the underlying database, but what if he were not mimicking the underlying database?
If he were building an application based on various or unknown future data sources, then the services layer can unify, re-present, simplify and aggregate those services, even if a large proportion of queries eventually back to a SQL Server in the next room.
Similarly, if you're building an application of massive scale, and by scale I mean millions of users expecting to wait a few seconds between actions, not millions of FX trades an hour, then placing a services layer between your application the data is a common pattern. The scalability of the internet is based on many small stateless HTTP servers and the caching infrastructure in between.
In real life, the same queries are run countless times, people refresh pages or click the same link over and over. No one really asks for 10m rows, because not many humans can look at it in one go. So working in small pages keeps the data flowing and requests interleaving. You also have the opportunity to introduce a shared in RAM cache in the services layer, or even a RAM database.
You may even find that you need to shard your database or partition it between SQL and a key/value store. You can then do the joins in the middle tier, scaled out, and offload the joining and compute-intensive stuff away from the database server.
The rule with internet scale is that the database is your hot spot and you need to do everything you can to prevent anyone talking to it! Be that local HTTP cache in an iPad, in your ISPs proxy, in the IIS output cache, or in a Redis cache, all those layers are helping to spread the load, ease the burden.
So if Carl came to interview with me and told me he'd considered putting an OData layer before his SQL boxes, I'd be interested to hear his reasoning.
WCF 数据服务和 OData 支持 JSON,因此您可以利用它来最大限度地减少负载。另外,借助 WCF 数据服务,您可以完全控制数据访问。您不必滚动实体框架。您可以自定义一切。好处是使用 WCF 数据服务和 OData 可以完全为您处理协议结构。通过添加服务引用即可使用 MVC 中的服务。 WCF 数据服务在 WCF 上运行,因此您可以执行 OData 类型交付之外的其他 Web 服务,因此它非常灵活。
OData 的本质以及 WCF 数据服务处理 OData 的方式存在一些限制,但它们相当具体,如果它们出现在您的体系结构中,则有一些方法可以解决它们。
如果您的解决方案与单个 Web 应用程序隔离,那么将数据层嵌入到该应用程序中效果很好。但是,如果您需要让另一个应用程序或进程访问数据层或共享业务逻辑,那么探索将数据层放入 WCF 数据服务中的选项是非常值得的。例如,您可以编写一个 PowerShell 脚本来用 2 行代码调用 Web 服务方法。因此,如果您希望能够从 Web 应用程序和命令行或计划任务运行域逻辑,那么您的 WCF 数据服务层可以处理所有场景,而无需复制逻辑或代码。
给猫剥皮的方法有很多种。我在业务应用程序中使用了这两种方法,并且不会说应该避免其中一种。它们都工作良好,并提供大量价值,而且不会造成损害。
WCF Data Services and OData support JSON, so you can minimize the payload by leveraging that. Plus, with WCF Data Services you can completely control your data access. You don't have to roll Entity Framework. You can customize everything. The benefit is that the protocol structure is completely handled for you by using WCF Data Services and OData. And consuming the service from MVC is an Add Service Reference away. WCF Data Services runs on WCF so you have the ability to do other web services beyond just OData type delivery, so it is extremely flexible.
There are limitations here and there that come with the nature of OData as well as the way WCF Data Services handles OData, but they are fairly specific and if they arise in your architecture there are ways around them.
If you solution is isolated to a single web application, then having the data layer embedded in that application works well. But if you have any need whatsoever to have another app or process hit the data layer or shared business logic then exploring the option of putting your data layer in a WCF Data Service is well worth it. For example, you could write a PowerShell script to call a web service method in 2 lines of code. So if you have domain logic that you want to be able to run from your web app and from a command line or scheduled task then your WCF Data Service layer could handle that scenario for all without having to duplicate logic or code.
Many ways to skin a cat. I have used both approaches in business applications and would not say that one or the other should be avoided. They both work well and provide plenty of value without being detrimental.
公平地说,这种方法的好处可能超过了性能问题,这无疑是巨大的。以这种方式构建的应用程序的延迟会增加几个数量级,并且执行时的计算资源成本可能比进程内解决方案高出几倍。
话虽如此,在人力资源有限的开发场景中,这可能会效果更好。它允许承包商快速被雇用,以任何适合他们的语言非常快速地编写新屏幕或全新应用程序。开发人员可以比专有的本土解决方案更快地掌握最新进展。配置文件中不再有 sa 密码,如果需要,可以注入自定义安全层,统一日志记录和审核,将多个数据存储合并到一个一致的资源中。如果你有一个异构平台,你不需要编写SDK,它们已经用许多重要的语言编写了。 oData 与 MS Excel 配合得很好,这对许多组织来说是一个巨大的胜利。根据您的网络拓扑,如果您位于远程办公室或防火墙后面(例如在进行演示的客户端站点),通过互联网路由可能比使用租用线路更便宜甚至更快。
对于大型数据集,请求和打包的开销变得不那么重要。例如,用于报告场景。虽然我从未设计过这样的东西,但我可以看到在内部使用 oData 端点可能有用,具体取决于您的企业文化和可用资源。
To be fair, there are benefits to this approach that may outweigh the performance concerns, which are admittedly tremendous. An application built this way will have orders of magnitude more latency and may cost several times more in compute resources to execute than an in-process solution.
That having been said, in development scenarios where human resources are limited, this may work better. It allows for contractors to be quickly hired on to write new screens or whole new applications very quickly in whatever language suits them. Developers can get up-to-speed faster than a proprietary homegrown solution. No more sa passwords in config files, injection of a custom security layer if required, unified logging and auditing, combining several data stores into one consistent resource. If you have a heterogenous platform, you don't need to write SDKs, they have already been written in many important languages. oData works very well with MS Excel, which is a huge win at many organizations. Depending on your network topology, it might be cheaper and even faster to route out over the internet than to use a leased line if you're in a remote office, or behind a firewall (at a client site doing a demo, for instance).
For large datasets, the overhead of the request and packaging becomes less important. For reporting scenarios, for instance. While I have never designed something like this, I can see where it might be useful, depending on your corporate culture and available resources, to consume oData endpoints internally.