What do others think of the crippled new EntitySet?

EntitySet used to implement IQueryable<T>, but no longer:

http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=1968147&SiteID=1

I understand the reason cited for dropping IQueryable support, but the cost seems excessive...

For a start, there's a confusing lack of symmetry now. The following Northwind query, for instance, executes entirely on the server, as an efficient SQL query:

var queryServer =
from e in dataContext.Employees
where e.City == "Redmond"
select new
{
e.Title,
TotOrders = e.Orders.Count
};

Yet the next query pulls every order processed by an employee to the client, which is highly inefficient:

Employees emp = dataContext.Employees.First (e => e.City == "Redmond");
var queryClient =
new
{
emp.Title,
TotOrders = emp.Orders.Count
};

This can be worked around by restructuring the query, but why allow such a trap in the first place? And how do you go about explaining to a newbie why the first query doesn't also cause this inefficiency, without making LINQ seem complex and nuanced? The confusion is further exacerbated by the fact thatdataContext.Orders.Count()does execute efficiently.

A more important issue is that lack of IQueryable support in EntitySet kills query composability. For instance, it's now impossible to write the following method:

void QueryEmployeeOrders (Expression<Func<Orders, bool>> orderFilter)
{
var queryServer =
from e in dataContext.Employees
select new
{
e.Title,
e.FirstName,
e.LastName,
...
TotalOrderCount = e.Orders.Count,
SelectedOrders = e.Orders.Where (orderFilter)
};

...
}


This will not compile - and right now there is no intuitive workaround. The dynamic query sample cannot help out becausee.Ordersdoes not implement IQueryable<>.

The only viable solution is to copy and paste this method for each predicate variation. But is this really where we want to head?

Joe

[2616 byte] By [JoeAlbahari] at [2008-1-8]
# 1

I agree that this is a problem; the ability to compose LINQ queries in such a simple manner is one of it's biggest attractions, IMHO. I can understand the difficulty in reconciling the Add/Remove semantics of the EntitySet with the query composition, but think that this approach is the wrong solution.

The options provided in the initial post as alternatives really don't work for me - the dynamic query code in Dynamic.cs is very clever, but it looses a whole pile of static type checking - at that point, the advantages of LINQ over building SQL strings are less apparent. And the idea of asking junior developers to use Expression factories and a "touch of reflection" is pretty unrealistic.

I've not had time to think through all the various problems that may exist if Add/Remove and IQueryable are both supported, but naively I would much prefer to have both, and to have a runtime exception thrown if I attempt to compose a new query from an entity set on which Add or Remove have been called. In my experience, large areas of applications deal with querying and displaying data (and hence benefit from IQueryable) whereas the parts that perform updates (and hence might have to handle the runtime exceptions) are much smaller.

The alternatives appear to be duplicated code or Dynamic.cs, neither of which sound great to me.

Cheers,

Steve

SteveStrong at 2007-10-2 > top of Msdn Tech,Visual Studio Orcas,LINQ Project General...

Visual Studio Orcas

Site Classified