首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >WCF OData服务存储过程调用使用$select选项生成“操作可能破坏运行时稳定”错误

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

Stack Overflow用户
提问于 2014-12-09 09:03:19
回答 1查看 1.7K关注 0票数 1

我一直试图通过实体框架和(OData)调用存储过程。它返回一个实体,而不是一个复杂的类型。下面是在web上找到的演练(比如这个),我在服务中找到了下面的代码:

代码语言:javascript
复制
[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。调试时,上面的方法运行时没有任何错误,但它返回操作可能会在到达客户端时破坏运行时错误的稳定性。经过这么多的研究,显然这是一个非常普遍的错误,指出了许多不同的原因。我还没有找到一个真正符合我的问题。最接近的是,但没有一种解决方案适合我。

此外,从上文第二条来看:

这是已知的WCF DS的限制。..。 第二,有些查询不能正常工作,因为little在某些情况下需要与little几乎不同的LINQ表达式。这就是你所看到的问题。

它已于2012年发布。如果是真的,还没有更新吗?还有其他方法可以让$select在存储的proc调用上工作吗?

TL;DR:

Works:

代码语言:javascript
复制
~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

不工作:

代码语言:javascript
复制
~WcfService.svc/GetEntitiesByParameterId?parameterId=1&$select=name

技术细节:

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

*我也尝试过升级到EF6和WCF 5.6.2,但仍然没有成功。

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

更新:在进一步摸索之后,我尝试不遍历存储过程,只返回手动构造的List<Entity>,然后将其作为queryable返回。惊讶地发现,当使用$select时,它仍然存在相同的错误。这可能是WCF服务操作的限制,而不仅仅是针对存储过程调用。我回到了文档,它确实显示了其他OData查询(top、展开和orderby)的使用情况,但没有显示关于$select的任何内容。

这只是通过我的测试观察,因为我找不到这个特定问题的很多来源。欢迎任何澄清和其他文件。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-12-17 08:55:06

根据Layla的评论,$select仍然不受支持,尽管我找不到任何关于它的确切文档。

据我所收集和观察到的,$select中断了存储过程调用,因为它试图更改已经从数据库获取的数据形状,并尝试返回一个动态实体。有关返回ObjectResult的存储过程的某些内容可能会使其陷入混乱。至于为什么硬编码的List<Entity>不能工作,我完全不知道。不过,不要引用我的话。正如我所说,这些只是我的观察。

解决方案:,我找到了一个简单而优雅的解决方案。由于我的存储过程只从数据库获取数据,并且不以任何方式更改数据(插入、更新、删除),所以我尝试使用表值函数返回与EF上的实体等效的表。我发现在服务操作方法上调用这个函数会返回一个IQueryable<Entity>,这基本上就是所需要的。$select现在也可以工作,其他OData查询选项也是如此。

步骤:

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

数据库功能:

代码语言:javascript
复制
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:

代码语言:javascript
复制
[WebGet]
public IQueryable<Entity> GetEntity(int parameter)
{
     return CurrentDataSource.GetEntity(parameter);
}

它并不能真正解决存储过程问题,但我将其标记为“答案”,直到有人能够提供更好的答案,因为它确实解决了我想要做的事情。

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27374947

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档