使用apicontroller vs odata EntitySetController

dav*_*pez 22 odata asp.net-web-api

我刚刚开始学习ASP.NET Web API,我还有几件事情仍然不清楚:

  • 为什么我应该使用EntitySetController,它继承自odata控制器而不是ApiController
  • 为什么在OData的上下文中经常提到EF.我知道它"代表"一个实体,但我不明白为什么这两个是连接的.第一个是服务层,EF是模型.
  • 我已经阅读并理解了很多关于这个主题的文字,是的,我错过了它的最佳实践

非常感谢,大卫

tne*_*tne 41

为什么我应该使用EntitySetController,它继承自odata控制器而不是ApiController

  • 我同意这是令人困惑的,并且文档似乎缺乏(至少当我遇到与你相同的问题时).我放松心情的方式就是简单地阅读代码.我鼓励你这样做,因为它真的很短(专注于EntitySetController类及其助手); 不应超过5-10分钟(承诺),之后你不会有任何问题.

    简短的故事是它为常见案例消除了一些样板(但如果你想要更多的背景和意见,继续阅读).

为什么在OData的上下文中经常提到EF.我知道它"代表"一个实体,但我不明白为什么这两个是连接的.第一个是服务层,EF是模型.

  • 这个人也无休止地困惑我,直到我放弃并查看OData的起源,WCF数据服务(以前的ADO.NET数据服务)和OData规范(暗示OData核心协议版本仍然带有标题指定称为"DataServicesVersion").在那里你可以发现OData使用EDM,实体数据模型,它与EF使用的模型规范相同,并以与EF:CSDL(概念模式定义语言)相同的格式对其进行序列化 .这并非巧合,WCF数据服务对EF提供了主要支持,虽然它不需要它,但可以说它的设计是基于它的.

    请注意,WCF数据服务仍然是OData的旗舰实现.

可能具有高度兴趣的东西(至少对我来说是这样):当使用EF与ASP.NET Web API和OData扩展时,没有办法(据我所知)在两者之间共享模型.

如果你没有发现这个有趣的话,你可以跳到下一个答案的下一个要点.

例如,在Code-First设置中使用EF时,通常会主要基于代码约定和EF System.Data.Entity.DbModelBuilder("流体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扩展在运行时从CLR代码(使用单独的代码约定)继续生成它们自己的序列化CSDL代码本身由EF从初始CSDL通过T4模板生成.你的头旋得多吗?


更新:这在两周前(7月19日)略有改善,对不起,我错过了.(感谢RaghuRam Nadiminti.)我没有查看补丁,但是从示例代码看,它的工作方式似乎是必须使用EF EDMX序列化器将模型序列化为CSDL,然后使用EdmLib解析器对其进行反序列化由OData扩展使用.它仍然感觉有点像EF Code-First设置中的hack(至少CLR代码只分析一次,但如果两个组件都使用相同的内存模型,我会更喜欢它).但是,在使用Model-First或Database-First方案时,可以通过直接反序列化VS生成的EDMX文件来获取快捷方式.在最后一个场景中,它实际上感觉不像是黑客,但同样,单个模型最好.我不知道EF可能会转向使用EdmLib,或者EdmLib会转而使用EF的EDM模型,这两个项目现在都非常强大,而且阻挡器可能不仅仅是技术问题.不幸的是,ASP.NET团队对AFAICT无能为力.



更新:随机偶然发现了那些会议记录.他们确实来自EF团队,并表示他们不打算在EdmLib上工作.


但是,我现在相信这是一件好事.原因是,如果他们缩小所有间隙,并删除所有样板,并使一切正确,它们将基本上最终到达WCF数据服务的位置,这是一个完全集成的解决方案,程序员通过"管道中注入代码"拦截器".对我来说,去那里的唯一原因是因为开源要求,但即便如此,我认为尝试提倡开源WCF-DS更合理.

现在的问题是:"但是什么是Web API + OData扩展适合的呢?".嗯,当你真的需要两种不同的模型用于数据存储和Web服务时,这是一个很好的选择.当"拦截器"设计不够灵活,您无法在两个模型之间进行转换时,这是一个很好的选择.


更新:由于2014年3月27日,它的官员,他们将试图弥补这些差距,自嘲WCF数据服务的过程.很早就会提到一个"处理程序"来执行此操作,很可能是一个ASP.NET HTTP处理程序(请参阅有关公告的评论).看起来很少有计划进入这个,因为他们仍在集思广益,以使ASP.NET Web API填补WCF数据服务的使用案例.我在上面提到了这些用例,在对公告的评论和这个帖子中(在公告前几天开始).

许多其他人表达了几乎相同的担忧(再次,看到相互关联的讨论),所以很高兴看到我没有梦想这一切.

有些人不相信ASP.NET Web API可以在合理的时间内变成对数据服务用例有用的东西,因此有些人建议MSFT重新考虑他们的决定.是否将ASP.NET用于开源要求的问题也没有实际意义:如果一切顺利,WCF数据服务将很快开源,尽管不是因为任何倡导工作.(这只是一个源转储,目前还不知道是否有人会维护它.)

从我可以收集到的,一切都指向削减预算,有些人谈论它是全公司"重新聚焦"的结果,尽管所有这一切都应该采取一些盐.

除了这些之外,现在有可能随着时间的推移出现一个新的解决方案 - 当涉及到OData API时,WCF数据服务或Web API会更好.虽然它现在看起来有点混乱,但MSFT OData团队确实从相对较早的客户那里收到了相当多的反馈,所以有希望(特别是如果未来的解决方案,如果有的话,本身就是开源的).过渡可能会很痛苦,但请务必在未来围绕这个讨论.

我不确定我是否会花时间更新这篇文章; 我只是想突出一点,关于Web API和数据服务的事情即将发生很大的变化,因为这个答案仍在不时被推翻.



更新: RESTier(公告)似乎是结果.


最后,我的(个人)意见:OData,尽管在技术上是基于REST的HTTP协议,但是非常非常非常以数据为导向.这绝对没问题(我们可以使用HTTP定义很多不同类型的接口),而且,我发现所有的ServiceStack与OData辩论无关(我相信它们在我们当前的常见架构中的不同层运行).我发现令人担忧的是,人们试图使基于OData的API像行为中心(或"面向流程",或"ServiceStack"一样)API.对我来说,OData URI约定和资源表示格式(Atom和JSON)一起取代SQL,WCF数据服务"查询拦截器"和"更改拦截器"取代DBMS触发器和OData操作取代DBMS存储过程.通过这种观点,您可以立即看到,如果您需要放置OData API的域逻辑过于复杂或者不是面向数据,那么您最终将会遇到不符合REST原则的错综复杂的"操作",并且感觉不对的实体.如果您将OData API视为纯数据层,那么您没问题.您可以在其上堆叠服务,就像在SQL数据库上放置"服务层"一样.

因此,我不确定Web API + OData扩展是否那么好.如果你需要从根本上不同的模型,你的应用程序可能不是太过于数据导向(除非你只是简单地合并各种来源的模型),因此OData不适合.这是一个标志,你至少应该考虑单独的Web API(下面是SQL或OData)或类似ServiceStack的东西.

无论好坏,Javascript客户端都无法将SQL与远程服务器对话.也许将来可以通过浏览器API,或者可能通过WebSockets的变体,但是现在,OData是最接近远程数据层的东西,任何人都可以获得具有瘦服务器端逻辑或没有服务器端逻辑的丰富JS​​客户端.OData当然被其他类型的客户端使用,但我想说它在客户端Web平台上特别有用,其中像Breeze.js或JayData这样的东西对于OD实体框架对SQL来说是什么.

我已经阅读并理解了很多关于这个主题的文字,是的,我错过了它的最佳实践

  • 别担心,我环顾四周,但我认为没有人真正知道他们在做什么.当你弄清楚这个烂摊子的时候,就像其他人一样假装.