4 ms·
> I think perhaps he is confusing best practices for public interfaces with general-purpose best practices. Exactly. Most of the advice in the article is sens
by davidp 14y ago
> I think perhaps he is confusing best practices for public interfaces with general-purpose best practices.
Exactly. Most of the advice in the article is sensible when viewed from that perspective.
I use LINQ to Entity in my company's service API. If you fail to "seal" the query (as he calls it) with ToList() before you leave the 'using' block for your DB context, your callers get a runtime error later since the IQueryable isn't run until the caller enumerates it (i.e. after the 'using' block has disposed the DB context). (On the other hand, if you call ToList() too early in your method chain, you're preventing L2E from composing your expression tree into optimal SQL, since everything after ToList() is run client-side.)
As an API provider you have to treat the behavior of your return values as part of the contract, and if your caller is expecting a plain IEnumerable (like you claim to return in your method signature), you'd best make sure it isn't really an IEnumerableThatDependsOnNondeterministicContext or an IEnumerableWithUnpredictableSideEffects.
His point is spot on about returning IQueryable only when your intention is for the caller to compose your result with other queries. If you're just returning an IQueryable because you think it's cool to defer execution, you're probably missing the point. Deferred execution isn't 100% win; you can just as easily defer yourself into a timeslot when there's more contention for a resource as into one where there's less contention. In many cases it's just as well to declare your need for the data (e.g. by calling ToList() as early as possible and let the system manage the execution.
- bunderbunder 14y agoThat reminds me of another one I ran into. It's not specifically LINQ related, but does play into the problem with returning generators. A homegrown data access layer that would grab a SqlDataReader and then yield each item. That ended up creating all sorts of problems, up to and including a serious deadlocking issue at the database end of things.