我一直在尝试通过实体框架和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查询选项也可以使用。
脚步:
CurrentDataSource.<FunctionName>()
编码
数据库功能:
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] 删除。
我来说两句