如何将lambda表达式传递给WCF服务?
我目前的项目是使用IDesign架构,所以我的所有层都是服务。 我希望在我的资源访问层的CRUD中使用我的Read方法以lambda表达式的forms获取谓词以及要拉取的相关对象列表。 这样,资源访问层将非常通用。
[OperationContract] Result ReadObjects(Func predicate, string[] includes);
现在我来发现一些应该是显而易见的事情,那就是我无法序列化lambda表达式。 我研究了将字符串解析为lambda表达式,但这也是不行的。
有什么方法可以用来将lambda表达式传递给服务吗? 有没有更好的方法来做我想做的事情?
也许动态查询可以适用于您的情况?
您可以将where子句字符串传递给服务,该服务将validation并将其转换为表达式
我们必须在LINQ-to-Just-About-Everything中解决这个问题。 例如,在执行LINQ-to-SQL时:
var results = from c in customers where c.City == "London" select c.Name;
不知何故lambdas的内容c=>c.City == "London"
和c=>c.Name
需要以服务器理解的forms在SQL服务器上结束。 很明显,我们不能将lambda保存到服务器上。
相反,我们所做的是将lambda转换为表达式树,在运行时分析表达式树,从中构建实际的SQL字符串,并将该字符串发送到服务器进行处理。
你可以做同样的事情。 为您的服务器创建查询语言。 在客户端,将lambdas转换为表达式树。 在运行时分析它们,将结果转换为查询语言中的字符串,然后将查询发送到服务。
如果您对LINQ中的工作原理感兴趣,那么LINQ-to-SQL架构师Matt Warren已经编写了一系列关于如何自己完成的博客文章:
http://blogs.msdn.com/b/mattwar/archive/2008/11/18/linq-links.aspx
WCF不提供开箱即用的function。 您基本上必须编写一个自定义序列化程序,该序列化程序使用lambda表达式并将表达式树转换为可序列化的数据。
这就是WCF DataServices的工作方式。 您在客户端代码中使用lambda,它将这些lambda表达式分解为字符串,它将查询字符串传递给数据服务,然后将字符串转换回lambda,它应用于服务器端的IQueryable。
可行,但您必须为此编写大量自定义序列化代码。 另外,我们要清楚,这些是lamdba表达式 ,而不是包含随机代码的完整lambda方法,这些方法可以在服务器端执行。
我在CodePlex上使用这个库来序列化/反序列化表达式树(但它的先前版本),它完成了工作。
这里还有一些类似的问题: 在C#中序列化和反序列化表达式树
创建一个查询对象并将其传递给您的服务。
看看这是否有帮助:
一个例子:
var search = new AlbumSearch(); search.PriceFrom = 5; search.PriceTo = 10; search.Artist = new ArtistSearch(){ Name = "Metallica" }; search.Genre = new GenreSearch(){ NameContains = "Metal" }; var albuns = from x in repository.All(search.GetExpression()) select x;
我发现codeplex中的一个项目开源是这个问题的解决方案
表达式树序列化器
项目描述.NET 4.0和Silverlight 4类库,用于序列化和反序列化表达式实例。 另外:Silverlight的WCF IQueryable LINQ Provider和Web Http(REST)客户端提供了比WebClient更易于使用的简化REST客户端API(即WCF的WebChannelFactory)。
在这个链接上
- 如何在注册表中更改文件类型关联?
- 使用非法变量字符在C#中反序列化json
- 使用HMAC-SHA1加密创建OAuth签名返回HTTP 401
- 什么是用户界面设计模式中的模型,如MVC,MVP,MVVM?
- 实现自己的LINQ和IEnumerable
- System.Web.Script.Serialization.JavaScriptSerializer或System.Runtime.Serialization.Json.DataContractJsonSerializer?
- 阻止XmlReader扩展XML实体
- System.Threading.Timer vs System.Threading.Thread.Sleep resolution – .NET Timer不使用系统时钟分辨率
- 如何在虚拟模式下向ListView添加/删除项目?