非通用AsEnumerable

时间:2010-09-27 14:36:28

标签: c# linq

您如何建议在非通用AsEnumerable上使用IQueryable

在调用Cast<T>之前,我无法使用OfType<T>IQueryable<object>方法获取AsEnumerable,因为这些方法通过基础{{1}进行了明确的翻译如果我将它们与非映射实体一起使用(显然对象未映射),将会破坏查询转换。

现在,我有自己的扩展方法(下图),但我想知道框架中是否有内置方法。

IQueryProvider

所以,通过上面的扩展方法,我现在可以做到:

public static IEnumerable AsEnumerable(this IQueryable queryable)
{
    foreach (var item in queryable)
    {
        yield return item;
    }
}

4 个答案:

答案 0 :(得分:4)

JaredPar换句话说:

public static IEnumerable AsEnumerable(this IEnumerable source)
{
    return source;
}

用法:

IQueryable queryable = // ...
IEnumerable enumerable = queryable.AsEnumerable();
IEnumerable<Foo> result = enumerable.Cast<Foo>();
//                                     ↑
//                           Enumerable.Cast<TResult>(this IEnumerable source)

答案 1 :(得分:4)

由于接口IQueryable继承自IEnumerable,为什么不:

IQueryable queryable;
IEnumerable<T> = (queryable as IEnumerable).Cast<T>();

修改
有两种Cast<>扩展方法:

public static IQueryable<TResult> Cast<TResult>(this IQueryable source)
public static IEnumerable<TResult> Cast<TResult>(this IEnumerable source)

调用哪一个是由编译器静态决定的。因此,将IQueryable转换为IEnumerable会导致调用第二个扩展方法,将其视为IEnumerable

答案 2 :(得分:3)

类型IQueryable继承自非通用IEnumerable,因此此扩展方法似乎没有任何用途。为什么不直接将它用作IEnumerable

答案 3 :(得分:3)

为了澄清,您正在尝试添加&#34;强制表达式评估&#34;到您的linq表达式树,以便表达式树的一部分针对底层提供程序(例如linq to SQL)进行计算,其余部分在内存中计算(linq到对象)。但是您希望能够指定整个快速树而无需实际执行查询或将任何结果读入内存。

这是一件好事,它显示了对Linq工作方式的一些了解。干得好。

我在这里看到的困惑是你使用&#34; AsEnumerable&#34;作为方法名称。对我来说(我认为很多人瘦身linq)&#34; AsEnumerable&#34;太过类似于&#34; AsQueryable&#34;方法本质上是一个演员,而不是一个实际的评估者。我建议你将你的方法重命名为&#34;评估&#34;。这是我个人Linq扩展库中的Evaluate()方法。

    /// <summary>
    /// This call forces immediate evaluation of the expression tree. 
    /// Any earlier expressions are evaluated immediately against the underlying IQueryable (perhaps
    /// a Linq to SQL provider) while any later expressions are evaluated against the resulting object
    /// graph in memory.
    /// This is one way to determine whether expressions get evaluated by the underlying provider or
    /// by Linq to Objects in memory.
    /// </summary>
    public static IEnumerable<T> Evaluate<T>(this IEnumerable<T> expression)
    {
        foreach (var item in expression)
        {
            yield return item;
        }
    }

    /// <summary>
    /// This call forces immediate evaluation of the expression tree. 
    /// Any earlier expressions are evaluated immediately against the underlying IQueryable (perhaps
    /// a Linq to SQL provider) while any later expressions are evaluated against the resulting object
    /// graph in memory.
    /// This is one way to determine whether expressions get evaluated by the underlying provider or
    /// by Linq to Objects in memory.
    /// </summary>
    public static IEnumerable Evaluate(this IEnumerable expression)
    {
        foreach (var item in expression)
        {
            yield return item;
        }
    }

这允许您编写一个查询,其中某些查询由SQL计算(例如),其余查询在内存中计算。好事。