我一直试图通过实体框架和(OData)调用存储过程。它返回一个实体,而不是一个复杂的类型。下面是在web上找到的演练(比如这个一),我在服务中找到了下面的代码:
[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:
~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>,然后将其作为queryable返回。惊讶地发现,当使用$select时,它仍然存在相同的错误。这可能是WCF服务操作的限制,而不仅仅是针对存储过程调用。我回到了文档,它确实显示了其他OData查询(top、展开和orderby)的使用情况,但没有显示关于$select的任何内容。
这只是通过我的测试观察,因为我找不到这个特定问题的很多来源。欢迎任何澄清和其他文件。
发布于 2014-12-17 08:55:06
根据Layla的评论,$select仍然不受支持,尽管我找不到任何关于它的确切文档。
据我所收集和观察到的,$select中断了存储过程调用,因为它试图更改已经从数据库获取的数据形状,并尝试返回一个动态实体。有关返回ObjectResult的存储过程的某些内容可能会使其陷入混乱。至于为什么硬编码的List<Entity>不能工作,我完全不知道。不过,不要引用我的话。正如我所说,这些只是我的观察。
解决方案:,我找到了一个简单而优雅的解决方案。由于我的存储过程只从数据库获取数据,并且不以任何方式更改数据(插入、更新、删除),所以我尝试使用表值函数返回与EF上的实体等效的表。我发现在服务操作方法上调用这个函数会返回一个IQueryable<Entity>,这基本上就是所需要的。$select现在也可以工作,其他OData查询选项也是如此。
步骤:
CurrentDataSource.<FunctionName>()的WCF数据服务中创建服务操作码
数据库功能:
CREATE FUNCTION GetEntities(@parameter)
RETURN @entites TABLE(
[Id] [int],
[Name] [nvarchar](100),
...
)
AS
BEGIN
INSERT INTO @entities
SELECT [Id], [Name], ... FROM [EntityTable]
RETURN
ENDWCF:
[WebGet]
public IQueryable<Entity> GetEntity(int parameter)
{
return CurrentDataSource.GetEntity(parameter);
}它并不能真正解决存储过程问题,但我将其标记为“答案”,直到有人能够提供更好的答案,因为它确实解决了我想要做的事情。
希望这对其他人也有帮助。:)
https://stackoverflow.com/questions/27374947
复制相似问题