WCF OData Service存储过程调用使用$ select选项生成“操作可能破坏运行时的稳定性”错误

我谁也不是

我一直在尝试通过实体框架和WCF数据服务(OData)调用存储过程。它返回一个不是复杂类型的实体。继演练发现所有网站上(像这样的一个),我想到了我的服务这里面的代码:

[WebGet]
public IQueryable<Entity> GetEntitiesByParameterId(int parameterId)
{
     return CurrentDataSource.GetEntitiesByParameterId(parameterId).AsQueryable();
}

以这种方式调用proc:~WcfService.svc/GetEntitiesByParameterId?parameterId=1执行存储过程并返回应返回的实体。没问题。

一切正常,直到我尝试使用$ select OData选项,即。~WcfService.svc/GetEntitiesByParameterId?parameterId=1&$select=name在调试时,以上方法运行时没有任何错误,但是它返回一个Operation可能会在到达客户端时破坏运行时错误。经过大量研究,显然这是一个非常普遍的错误,指向许多不同的原因。我还没有找到真正符合我的特定问题的解决方案。最近的是这个这个,但没有一个解决方案在我结束工作。

同样,从上面的第二篇文章中:

这是WCF DS的已知限制。...

其次,由于在某些情况下LINQ to EF与LINQ to Objects所需的LINQ表达式几乎没有什么不同,因此某些查询将无法正常工作。这是您看到的问题。

它已于2012年发布。如果它是真实的,是否还没有更新?还有其他解决方法可以使$ select在存储的proc调用中起作用吗?

TL; DR:

作品:

~WcfService.svc/GetEntitiesByParameterId?parameterId=1
~WcfService.svc/GetEntitiesByParameterId?parameterId=1&$top=1
~WcfService.svc/GetEntitiesByParameterId?parameterId=1&$skip-5
~WcfService.svc/GetEntitiesByParameterId?parameterId=1&$filter={filter query}
~WcfService.svc/GetEntitiesByParameterId?parameterId=1&$expand=SomeNavigationProperty

不起作用:

~WcfService.svc/GetEntitiesByParameterId?parameterId=1&$select=name

技术细节:

EntityFramework 5,WCF数据服务5.0,OData V3

*我还尝试了升级到EF6和WCF 5.6.2,但仍然无法正常工作。

任何帮助,将不胜感激。谢谢!


更新:经过一番摸索之后,我尝试不通过存储过程,而只是返回一个手动构造的List<Entity>然后将其返回为可查询的形式。惊讶地发现使用$ select时它仍然具有相同的错误。这可能是WCF服务操作的限制,而不仅限于存储过程调用。我回到文档中,它确实显示了其他OData查询(顶部,展开和订购)的用法,但与$ select无关。

这只是通过测试得出的观察结果,因为我找不到有关此特定问题的大量信息。欢迎任何澄清和其他文档。

我谁也不是

根据Layla Liu MSFT的评论,尽管我找不到任何关于它的权威性文件,但仍不支持$ select。

根据我的观察和观察,$ select中断了存储过程调用,因为它试图更改已经从数据库中获取的数据形状,并尝试返回一个动态实体。关于存储过程返回ObjectResult的某些信息可能会使它混乱。至于为什么硬编码List<Entity>不起作用,我没有任何想法。但是,请不要在此引用我的信息。正如我所说的,这些只是我的观察。

解决方法:不过,我找到了一种简单而优雅的解决方法。由于我的存储过程仅从数据库中获取数据,并且不以任何方式更改数据(INSERT,UPDATE,DELETE),因此我尝试使用表值函数返回与EF上的实体等效的表。我发现在Service Operation方法上调用此函数会返回,IQueryable<Entity>这基本上是需要的。$ select现在也可以使用,其他OData查询选项也可以使用。

脚步:

  1. 在数据库上创建一个函数
  2. 更新EDMX->添加功能
  3. 添加具有实体返回类型的新功能导入
  4. 在调用的WCF数据服务中创建服务操作 CurrentDataSource.<FunctionName>()
  5. 在提琴手中测试。

编码

数据库功能:

CREATE FUNCTION GetEntities(@parameter)
RETURN @entites TABLE(
    [Id] [int], 
    [Name] [nvarchar](100),
    ...
)
AS
BEGIN      
    INSERT INTO @entities
       SELECT [Id], [Name], ... FROM [EntityTable]

    RETURN      
END

WCF:

[WebGet]
public IQueryable<Entity> GetEntity(int parameter)
{
     return CurrentDataSource.GetEntity(parameter);
}

它并不能真正解决存储过程的问题,但是我将其标记为答案,直到有人可以提供更好的解决方案为止,因为它确实解决了我要尝试做的事情。

希望这对其他人也有帮助。:)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章