在WCF服务中暴露IQueryable

12

我一直在学习IQueryable和查询的延迟加载/延迟执行。

是否可能通过WCF暴露此功能? 我想公开一个LINQ-to-SQL服务,返回一个IQueryable,在客户端上可以对其进行其他查询,并最终使用.ToList()执行。 在这种情况下,OData格式适用吗?

如果可能,这种技术的术语是什么,有哪些好的教程可供我参考? 谢谢。


对于Silverlight,您可以使用WCF RIA服务。 - RichardOD
6个回答

11
您应该查看WCF数据服务,它可以让您在客户端定义Linq查询。WCF数据服务可能是您需求的唯一解决方案。
IQueryable仍然只是一个接口,其功能取决于实现接口的类型。您不能直接公开Linq-To-Sql或Linq-To-Entities查询。存在多个原因,例如生命周期短暂的上下文或序列化,这将执行查询,因此客户端将获取所有对象的列表而不是查询结果。

1
据我所知,DataContext 不可序列化,这意味着您无法通过 WCF 传递它。

1

https://remotelinq.codeplex.com/ 是另一个选择。但它需要在 AppDomain 中扫描当前程序集并对其进行序列化。这种技术不适用于 WinRT,因为 WinRT 应用程序没有域。


1

您可以使用http://interlinq.codeplex.com/,它允许您通过WCF发送Linq查询。

只有使用webHttpBinding才能使用WCF数据服务,并且不能表达所有Linq查询。在使用WCF数据服务时编写查询不太吸引人-需要使用字符串表达式,例如:

.AddQueryOption("$filter", "Id eq 100");

0

我一直在苦苦思索同样的问题,并意识到一个良好构建的问题就是解决了一半的问题。

IQueryable基本上用于在将查询发送到您的DB调用之前过滤查询,因此您首先获得的是那10个记录,而不是获取1000个记录然后再筛选出10个。这种过滤属于您的服务层,但如果您正在构建API,则应该使用AND/OR参数在URL中进行映射。

http://{host}/{entity}/q?name=john&age=21.

因此,您最终会得到类似于以下内容:

Filter:Column1=Value1 > http://{host}/{entity}q?column1=value1 >  SELECT *
                                                                  FROM  Entity
                                                                  WHERE Column1=Value1

MVC                   > WCF                                    >  DB

你可以在[这里]找到一个非常好的示例。

最后,由于来自WCF的有效负载很可能是JSON格式,因此您应该将它们反序列化到集合中的域模型中。直到这一点,分页才应该发生,因此我建议进行一些WCF缓存(由于它是HTTP,所以非常简单)。您仍将在WebApp端使用LINQ,只是没有“WHERE” LINQ子句(除非您想动态创建上面表达的URL?)

对于复杂的OR查询,您可能会得到多个WCF查询(每个“AND”一个),然后将它们全部连接起来。


-1
如果可以通过WCF发送IQueryable<>,从安全角度来看并不是一件好事,因为IQueryable<>可能会暴露像数据库连接字符串之类的东西。但是前面的一些评论似乎很有前途。

“从安全角度来看,这不是一件好事”……这不取决于 IQueryable 的具体实现方式吗? - Crono

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接