[Silverlight入门系列]WCF RIA Services应该返回IQueryable<T>还是IEnumerable<T>?
在WCF RIA Services的Domain Services类中,我们经常这样写来返回IEnumerable<T>:
1: [EnableClientAccess()]
2: public class CustomerService : DomainService
3: {
4: private ICustomerRepository _customerRepository;
5:
6: public CustomerService(ICustomerRepository customerRepository)
7: {
8: _customerRepository = customerRepository;
9: }
10:
11: [Query]//可省略
12: public IEnumerable<Customer> GetCustomers()
13: {
14: //Use _customerRepository
15: }
16: }
客户端调用:
1: var customerContext = new CustomerContext();
2: customerContext.Load<Customer>(customerContext.GetCustomers());
或者返回IQueryable<T>,这样写:
1: [EnableClientAccess()]
2: public class CustomerService : DomainService
3: {
4: [Query]//可省略
5: public IQueryable<Customer> GetCustomers()
6: {
7: _myObjectContext.Customers;
8: }
9: }
论强悍,显然是IQueryable<T>!
每一个返回IEnumerable<T>的DomainService方法参数对客户端来说是固定的,这是最大缺陷;而返回IQueryable<T>就灵活多了,客户端可以用EntityQuery传Query表达式树(Expression)给服务端。用IQueryable<T>的好处显然要多于IEnumerable<T>,看看我这篇博文,就是使用EntityQuery和IQueryable<T>实现了MVVM的分页、排序、搜索、过滤,非常强悍,而且都是服务器端分页,服务器端排序。因为如果后台用EntityFramework或者LinqToSql,我们就可以把一个Query传给服务器端,而没有执行,直到真正的ToList()的时候(或者Count()),Query才真正到服务端执行,WCF RIA Services会触发这个Query并且EntityFramework或者LinqToSql会把这个Query转换为T-SQL语句到数据库执行。这样,我们可以真正的减少客户端和服务端传输的数据量,真正按需加载。而IEnumerable<T>实质是LinqToObjects,也就是说这个数据源已经生成,对这个本地数据源执行查询而已(不是针对远程数据源),LinqToObjects的处理结果是把LINQ表达式映射成对应的委托/Action,而LinqToSql则是保存了一系列的"步骤"(表达式树/Expression的处理方式)。总之,一个是针对本地数据源,一个是针对远程数据源;一个是LinqToObjects,一个LinqToSql,理解了就好。
1: //IQueryable<T>例子:
2: public partial class MainPage : UserControl
3: {
4: private CustomerDomainContext _customerContext = new CustomerDomainContext();
5:
6: public MainPage()
7: {
8: InitializeComponent();
9:
10: EntityQuery<Customer> query =
11: from c in _customerContext.GetCustomersQuery()
12: where c.Phone.StartsWith("583")
13: orderby c.LastName
14: select c;
15: LoadOperation<Customer> loadOp = this._customerContext.Load(query);
16: CustomerGrid.ItemsSource = loadOp.Entities;
17: }
18: }
适合的才是最好的
既然这样,我们是不是要把DomainService里每一个方法都返回IQueryable<T>?停!!!这个要看使用场景了。
首先是业务逻辑的问题,如果你的应用是很简单的小型应用,没啥业务逻辑,那么推荐你都返回IQueryable<T>;如果你是大型商业应用,业务逻辑复杂,而且放在服务器端,那么应该在服务器进行复杂业务逻辑处理,完了返回IEnumerable<T>。
其次是数据量大小的问题,由于IQueryable<T>是按需加载,而IEnumerable<T>是本地数据,完全下载到内存中,所以前者即使有几十万条上千万条数据也不是问题,后者就不一定了。这些都要在系统设计的时候考虑到。
Reference - WCF RIA Services : HowTo
Prerequisites for WCF RIA Services
- Walkthrough: Installing and Configuring SQL Server 2008 R2 Express with Advanced Services
- Walkthrough: Installing the AdventureWorks OLTP and LT sample databases
Creating RIA Services Solutions
- Walkthrough: Taking a Tour of RIA Services
- Walkthrough: Creating a RIA Services Solution
- Walkthrough: Using the Silverlight Business Application Template
- Walkthrough: Creating a RIA Services Class Library
- Walkthrough: Localizing a Business Application
- How to: Create an Domain Service that uses POCO-defined Entities
- How to: Add or Remove a RIA Services Link
- Using the Domain Service Wizard
Deploying and Localizing a RIA Services Solutions
- Troubleshooting the Deployment of a RIA Services Solution
- Troubleshooting the Deployment of a RIA Services Solution
- Walkthrough: Localizing a Business Application
- Domain Services
- Data
- Shared Code
- Client Code Generation
- DomainContext and Operations
- DomainDataSource
- Error Handling on the Client
- Customizing Generated Code
Accessing non-Silverlight Clients
Authentication, Roles, and Profiles
- How to: Enable Authentication in RIA Services
- How to: Enable Roles in RIA Services
- How to: Enable Profiles in RIA Services
- How to: Create a Custom Authorization Attribute
- Walkthrough: Using Authentication Service with Silverlight Business Application
- Walkthrough: Using Authentication Service with Silverlight Navigation Application
