开发者

Will my LinqToSql execution be deffered if i filter with IEnumerable<T> instead of IQueryable<T>?

I have been using these common EntityObjectFilters as a "pipes and filters" way to query from a collection a particular item with an ID:

public static class EntityObjectFilters
{
    public static T WithID<T>(this IQueryable<T> qry,
       int ID) where T : IEntityObject
    {
        return qry.SingleOrDefault<T>(item => item.ID == ID);
    }

    public static T WithID<T>(this IList<T> list,
        int ID) where T : IEntityObject
    {
        return list.SingleOrDefault<T>(item => item.ID == ID);
    }
}

..but i wondered to myself: "can i make this simpler by just creating an extension for all IEnumerable<T> types"?

So i came up with this:

public static class EntityObjectFilters
{
    public static T WithID<T>(this IEnumerable<T> qry,
       int ID) where T : IEntityObject
    {
        return qry.SingleOrDefault<T>(item => item.ID == ID);
    }
}

Now while this appears to yield the same result, i 开发者_如何学Gowant to know that when applied to IQueryable<T>s will the expression tree be passed to LinqToSql for evaluating as SQL code or will my qry be evaluated in it's entirety first, then iterated with Funcs?

I'm suspecting that (as per Richard's answer) the latter will be true which is obviously what i don't want. I want the same result, but the added benefit of the delayed SQL execution for IQueryable<T>s. Can someone confirm for me what will actually happen and provide simple explanation as to how it would work?

EDIT:

Solution i went with

    public static T WithID<T>(this IEnumerable<T> qry,
        int ID) where T : DomainBase
    {
        if (qry is IQueryable<T>)
            return ((IQueryable<T>)qry).SingleOrDefault<T>(item => item.ID == ID);
        else
            return qry.SingleOrDefault<T>(item => item.ID == ID);
    }


No, when qry is typed as IEnumerable<T> it will call Enumerable.SingleOrDefault rather than Queryable.SingleOrDefault. The lambda expression will be converted into a delegate instead of an expression tree, and it won't use SQL.

Note that SingleOrDefault doesn't use deferred execution in the first place - it's always immediate - but the difference is where the querying is performed. You almost certainly want the database to do it. If you have a look at your logs with the simplified version, you'll see that all the results are being fetched - whereas with the IQueryable<T> overload the SQL will contain the relevant filtering.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜