我刚开始学习ASP.NET Web API,还有几件事情不太清楚:
- 为什么要使用EntitySetController,它继承自OData控制器,而不是ApiController?
- 为什么在OData的上下文中经常提到EF。我知道它“表示”一个实体,但我不明白它们两者之间的联系。前者在服务层上,而EF是模型。
- 我已经阅读并理解了很多相关的文献,但我错过了最佳实践的时间。
非常感谢,David
我刚开始学习ASP.NET Web API,还有几件事情不太清楚:
非常感谢,David
为什么我应该使用从OData Controller继承的EntitySetController而不是ApiController
我同意这很困惑,文档似乎缺乏(至少当我有和你一样的问题时)。我放心的方式是通过简单地阅读代码来消除我的疑虑。我鼓励你也这样做,因为它真的非常简短(专注于EntitySetController类及其helpers);最多只需要5-10分钟的时间(保证),并且之后你将不会有任何问题。
简而言之,它消除了一些常见情况下的模板代码(但如果您想要更多背景信息和观点,请继续阅读)。
这个问题也曾让我困扰了很久,直到我放弃并查看了OData的起源,WCF Data Services(之前是ADO.NET Data Services)和OData规范(提示是OData Core协议版本仍然使用名为“DataServicesVersion”的标头)。在那里,你可以发现OData使用EDM,即实体数据模型,这是EF使用的相同模型规范,并以与EF相同的格式序列化它:CSDL(概念模式定义语言)。这不是巧合,WCF Data Services对EF有着重要的支持,虽然它不需要,但可以说它的设计基于EF。
请注意,WCF Data Services 仍然是 OData的旗舰实现。
以下是一些可能非常有趣的内容(至少我认为很有趣):当使用EF与ASP.NET Web API和OData扩展时,据我所知,没有办法共享模型。
如果你觉得这个问题不感兴趣,可以跳到下一个问题。
例如,在使用EF进行Code-First设置时,您通常会根据代码约定和EF的System.Data.Entity.DbModelBuilder("fluid API")构建模型。然后,您将使用System.Web.Http.OData.Builder.ODataConventionModelBuilder来构建OData模型,几乎完全相同,并且得到几乎完全相同的结果。过去,我曾经从EF团队或Web API团队的某个随机会议中找到了一些随机笔记,其中简要提到了这一点,就我所知(我无法再找到此文档),他们没有计划改善这种情况。因此,现在他们有两个不同且不兼容的EDM实现。我承认我没有花时间仔细查看代码以正确验证这一点,但我知道Web API + OData扩展依赖于EdmLib(最初为WCF数据服务提供Microsoft.Data.Edm),而EF则不是这样,并且使用自己的System.Data.Entity.Edm实现。我也知道它们基于约定的模型生成器是不同的,如上所述。如果你在DB-First设置中使用EF,情况就变得荒谬了;你会在EDMX文件中获得一个以CSDL格式序列化的EDM模型,而OData扩展会在运行时从由EF从初始CSDL通过T4模板生成的CLR代码(使用单独的代码约定)中生成自己的序列化CSDL代码。你的头会晕吗?
问题现在变成了:“那么Web API + OData扩展有什么用处呢?”当你真正想要数据存储和Web服务两个不同的模型时,它非常适合。当“拦截器”设计对于你来说不够灵活,不能在两个模型之间进行转换时,它非常适合。
我已经阅读并理解了大量关于此主题的文献,但我错过了最佳实践的时间
如果您想创建一个OData端点,请使用EntitySetController。如果您想返回通用的JSON或XML,或者其他格式(例如使用自定义格式化程序),请使用ApiController。
在Web API中,EF和OData不一定是相互关联的。您可以编写一个不使用EF的OData端点。许多Web API教程使用EF,因为EF代码优先相对容易在教程中展示。:-)