Since we have a WCF RIA Services experts here, why not asking a question?
What is the difference between exposing an IEnumerable<T> vs IQueryAble<T> from a DomainContext?
Read some explanations but they didn’t convinced me…
.Corrado
The difference is when the LINQ query is actually executed. Lets say that your query methods look like this:
public IQueryable<Foo> GetFoos
{
return this.ObjectContext.Foos;
}
public IEnumerable<Foo> GetFoos2
{
return this.ObjectContext.Foos;
}
Then, in your client side code you execute the following loads:
Context.Load(Context.GetFoos(). Where(f => f.FooId = fooId);
Context.Load(Context.GetFoos2().Where(f => f.FooId - fooId);
On the first load (the IQueryable GetFoos) the DomainService combines the server side of the query with the client side of the query resulting in "this.ObjectContext.Foos.Where(f => f.FooId = fooId" getting executed against the database returning back the single row of data from the database which then gets sent to the client.
On the second load (the IEnumerable GetFoos2) all 2,000,000 Foo records in the database are pulled into the web server and then returned to the base DomainService. The DomainService then filters the 2,000,000 rows by the Where statement from the client and sends the one matching row back to the client, assuming that the service doesn't timeout first.
"Corrado Cavalli" <corrado...@gmail.com>
Sent by: wpf-di...@googlegroups.com
01/29/2010 02:13 PM CETPlease respond towpf-d...@googlegroups.com
To <wpf-di...@googlegroups.com>
cc
bcc
Subject [WPF Disciples] Question on WCF RIA Services...
That confirms my version.
Thanks a lot Colin!
.Corrado
Actually Colin, I think both versions benefit from deferred execution because underneath both are IQueryable (IQueryable<T> extends IEnumerable<T>). So the actual pull from the server doesn’t happen until you enumerate. When you enumerate either of these, the server request includes the where. I could be wrong because I always use IQueryable<T> to be explicit. So I’ll create a quick test just to make sure.
On Fri, Jan 29, 2010 at 11:33 AM, Michael D. Brown
<mike....@azurecoding.net> wrote:
> Actually Colin, I think both versions benefit from deferred execution
> because underneath both are IQueryable (IQueryable<T> extends
> IEnumerable<T>). So the actual pull from the server doesn’t happen until you
> enumerate. When you enumerate either of these, the server request includes
> the where. I could be wrong because I always use IQueryable<T> to be
> explicit. So I’ll create a quick test just to make sure.
>
>
>
> From: wpf-di...@googlegroups.com [mailto:wpf-di...@googlegroups.com]
> On Behalf Of CBl...@EKI-CONSULTING.COM
> Sent: Friday, January 29, 2010 10:05 AM
>
>
>
>
>
--
Quidquid latine dictum sit, altum sonatur.
- Whatever is said in Latin sounds profound.
War is peace. Freedom is slavery. Bugs are features.
I think my original answer is the "official" answer, but in reality (I just re-checked) there is no difference between IQueryable<T> and IEnumerable<T> within the actual RIA Services code. The result of calling your Get method is actually stored in an IEnumerable value behind the scenes and nothing checks the original return type of the get method. However, that is an implementation detail and there is no guarantee that a different implementation in the future will start checking the method's type instead.
Colin Blair
"Michael D. Brown" <mike....@azurecoding.net> Sent by: wpf-di...@googlegroups.com 01/29/2010 11:33 AM EST Please respond to wpf-di...@googlegroups.com |
To |
<wpf-di...@googlegroups.com> |
cc |
||
bcc |
||
Subject |
RE: [WPF Disciples] Question on WCF RIA Services... | |
I have developed a few patterns around RIA services that hide the dependency on Domain Context. But the answer to how it reduces round trips is actually cool. The domain context is a full LINQ provider just like EF or Linq to SQL. When you call LoadFoo on the domain context it actually returns an IQueryable<Foo>. The IQueryable is able stores the queries added onto it as Expressions. When enumerate is called on the queryable, it makes another call to the domain context which decomposes the expression and serializes it across the wire which gets executed on the server side. On the server side if your Load or Get function returns an IQueryable, the expression gets appended to the end of the Query chain and executed. If it returns an IEnumerable, then the query chain is executed server side against the IEnumerable that was retrieved.
Bada-bing bada-boom less data sent across the wire. It also supports lazy loading or eager loading (in some scenarios the conserving bandwidth is more important than reducing round trips you have full control over what’s more important). Loading object hierarchies is also supported for instance IQueryable<Employee> GetAllEmployees() can return Employees, Managers, and Executives over the wire without problems. This was a big deal to get into V1 and I’m glad we got it.
The great thing about it being WCF RIA Services is that it can be leveraged in WPF (especially using the new RIA Services Library template and the Silverlight 4 compatibility with non-Silverlight apps). So the same code can be leveraged across the Web, Silverlight, and WPF (of course the web will use the DomainService directly).
From: wpf-di...@googlegroups.com [mailto:wpf-di...@googlegroups.com] On Behalf Of Bill Kempf
Sent: Friday, January 29, 2010 12:17 PM
To: wpf-di...@googlegroups.com
Subject: Re: [WPF Disciples] Question on WCF RIA Services...
Yeah, I have to say my remarks were general remarks about the difference between IQueryable<T> and IEnumerable<T> in LINQ. The actual behavior depends on the provider, and I was wondering how a provider based on web services could possibly reduce the round trips. However, it's best practice to not concern yourself with implementation details, and therefor IQueryable should be preferred.
On Fri, Jan 29, 2010 at 12:10 PM, <CBl...@eki-consulting.com> wrote:
I think my original answer is the "official" answer, but in reality (I just re-checked) there is no difference between IQueryable<T> and IEnumerable<T> within the actual RIA Services code. The result of calling your Get method is actually stored in an IEnumerable value behind the scenes and nothing checks the original return type of the get method. However, that is an implementation detail and there is no guarantee that a different implementation in the future will start checking the method's type instead.
Colin Blair
"Michael D. Brown" <mike....@azurecoding.net> |
Sent by: wpf-di...@googlegroups.com 01/29/2010 11:33 AM EST Please respond to wpf-di...@googlegroups.com |
To | ||||
cc | ||||
bcc | ||||
Subject |
RE: [WPF Disciples] Question on WCF RIA Services... |
Apologies, strike my previous email from the record it was based on outdated information. In fact one of my utilities was built specifically to give this behavior to DomainContext. Within the generated DomainContexts are overloads for Load that take a query filter. The utility provides the IQueryable implementation that does defer loading until enumeration is called.