[Silverlight入门系列]WCF RIA Services应该返回IQueryable<T>还是IEnumerable<T>?

WCF RIA ServicesDomain 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>,看看我这篇博文,就是使用EntityQueryIQueryable<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

Creating RIA Services Solutions

Security for WCF RIA Services

Deploying and Localizing a RIA Services Solutions

Middle Tier

Silverlight Clients

Accessing non-Silverlight Clients

Authentication, Roles, and Profiles

End-to-EndScenarios

posted on 2011-10-22 20:48 Mainz 阅读(763) 评论(0) 编辑 收藏

导航

公告

统计