如果IQueryable <t>继承了IEnumerable <t>,那么IQueryable <t>是如何LINQ to SQL的呢?

时间:2017-03-30 09:56:21

标签: c# linq visual-studio-2015 ienumerable iqueryable

IEnumerable<T> case是LINQ-to-object,IQueryable<T>是允许LINQ-to-SQL的接口,但IQueryable<T>继承IEnumerable<T>,所以怎么可能到IQueryable<T>过滤数据库中的行,而IEnumerable<T>过滤内存中的对象?

2 个答案:

答案 0 :(得分:8)

您错误地认为继承和接口实现。

IQueryable<T>继承IEnumerable<T>,但与类之间的继承完全不同,其中派生类继承了基类的实现。接口只是契约,它们背后没有实际代码:

public interface IFoo
{
    void Foo(); //its simply a contract, no implementation at all.
}

public interface IBar: IFoo
{
    void Bar();
}

public class Foo: IFoo
{
    void Foo() { //Foo's sepecific implementation goes here }
}

public class Bar : IBar 
{
    void Foo() { //Bar's specific implementation goes here }
    void Bar() { //implementation goes here }
}

Bar通过IFoo实施IBar的事实并不意味着FooBar之间存在任何关系。

答案 1 :(得分:3)

  

当IEnumerable过滤内存中的对象时,IQueryable如何过滤数据库中的行?

他们没有,这是一个不准确的陈述。

实际的实现代码是扩展方法,它们对IEnumerable或IQueryable有选择性。

在EF中有一个

Where<T>(this IQueryable<T>, Expression<Predicate<T>> )

并且在System.Linq中有

Where<T>(this IEnumerable<T>, Predicate<T>)

resoluton规则将优先于基本Linq的IQueryable扩展,并通过Expression<>参数启用魔术。