这是一个有趣的问题,我希望有人可以帮忙。
我有一个DomainService类,其中包含以下查询:
[Query]
public IEnumerable<BatchResult> GetBatchResults(int batchId)
{
return ObjectContext.BatchQueries
.Include("BatchTCResults")
.Include("BatchANFResults")
.Where(x => x.BatchId == batchId)
.Where(x => x.BatchTCResults.Any() || x.BatchANFResults.Any())
.ToArray() // enumerate because projection calls a method that EF will poop it's pants on
.Select(x => new BatchResult
{
BatchQueryId = x.Id,
Route = x.Routing,
Account = x.Account,
Amount = x.Amount,
CheckNumber = x.CheckNumber,
Severity = BatchResult.DetermineOverallSeverity(x)
});
}
这可行但是我真的需要从Silverlight客户端传递的分页/排序信息在枚举发生在调用.ToArray()
客户端正在使用DomainDataSource Silverlight控件。
我怎样才能做到这一点?
答案 0 :(得分:3)
最简单的方法是将分页/排序/过滤参数添加到方法参数列表中,并将相应的LINQ查询运算符添加到服务方法中的数据上下文查询中。但是,在这种情况下,您将丢失客户端IQueryable
功能。我的意思是,客户端的查询只会到达应用程序服务器,但不会到达数据库。并且您需要DomainContext
和用户界面之间的某个图层:DomainDataSource
不太可能有用。
使用IQueryable
将查询结果公开为AsQueryable()
将无济于事,因为表达式树将无条件地编译为代码以执行LINQ-to-Objects运算符。
在第一种情况下使用参数以及在客户端查询对象上编写自己的IQueryable
包装器有点困难。此包装器将从查询表达式中提取参数,并将它们作为方法参数传递给服务。好吧,如果我有足够的业余时间,我只会尝试这个。
另一个困难的方法是在服务器端做类似的事情。可以在IQueryable
中获取一个DomainService
对象,该对象具有从客户端传递的表达式树。您需要覆盖DomainService.Query
方法。然后,您将能够提取与分页/排序相关的部分查询表达式,将其保存到字段,然后应用于数据库查询。但是,Query
方法对于给定DomainService
中的所有方法都是单一的。因此,您可能会以一个大表方法结束,该方法决定如何为每个服务查询方法执行操作。不用说,服务将变得非常困难。
总而言之,我强烈建议您选择第一个选项。