我目前的项目是使用IDesign架构,所以我的所有图层都是服务。我希望在我的资源访问层的CRUD中使用我的Read方法以lambda表达式的形式获取谓词以及要拉取的相关对象列表。这样,资源访问层将非常通用。
[OperationContract]
Result<MyObject> ReadObjects(Func<MyObject, bool> predicate, string[] includes);
现在我发现了一些显而易见的事情,那就是我无法序列化lambda表达式。我研究了将一个字符串解析为一个lambda表达式,但这也是不行的。
我可以使用任何方法将lambda表达式传递给服务吗?有没有更好的方法来做我想做的事情?
答案 0 :(得分:25)
我们必须在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
的内容需要以服务器理解的形式结束在SQL服务器上。显然我们不能将lambda保存到服务器上。
我们所做的就是将lambda转换为表达式树,在运行时分析表达式树,从中构建一个实际的SQL字符串,然后将该字符串发送到服务器进行处理。
你可以做同样的事情。为您的服务器创建查询语言。在客户端,将lambdas转换为表达式树。在运行时分析它们,将结果转换为查询语言中的字符串,然后将查询发送到服务。
如果您对LINQ中的工作方式感兴趣,LINQ-to-SQL架构师Matt Warren撰写了一系列博客文章,介绍如何自行完成:
http://blogs.msdn.com/b/mattwar/archive/2008/11/18/linq-links.aspx
答案 1 :(得分:6)
也许动态查询可以适用于您的情况?
您可以将where子句字符串传递给服务,该服务将验证并将其转换为表达式
答案 2 :(得分:4)
WCF不提供开箱即用的功能。您基本上必须编写一个自定义序列化程序,它使用lambda表达式并将表达式树转换为可序列化的数据。
这就是WCF DataServices的工作方式。您在客户端代码中使用lambdas,它将这些lambda表达式分解为字符串,它将查询字符串传递给数据服务,然后将字符串转换回lambda,并将其应用于服务器端的IQueryable。
可行,但您必须为此编写大量自定义序列化代码。另外,我们要清楚,这些是 lamdba表达式,而不是包含可能在服务器端执行的随机代码的完整lambda方法。
答案 3 :(得分:0)
我在CodePlex上使用this库来序列化/反序列化表达式树(但是它的先前版本),它可以完成工作。
此处还有一些类似的问题,如下所示: Serializing and Deserializing Expression Trees in C#
答案 4 :(得分:0)
创建Query Object并将其传递给您的服务。
看看这是否有帮助:
一个例子:
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<Album>(search.GetExpression())
select x;
答案 5 :(得分:0)
我发现codeplex中的项目开源是这个问题的解决方案
Expression Tree Serializer
项目描述 .NET 4.0和Silverlight 4类库,用于序列化和反序列化Expression实例。另外:Silverlight的WCF IQueryable LINQ Provider和Web Http(REST)客户端提供了比WebClient更易于使用的简化REST客户端API(即WCF的WebChannelFactory)。
在此链接上