El propósito de un proveedor de Linq es básicamente "traducir" los árboles de expresión de Linq (que se crean detrás de las escenas de una consulta) en el lenguaje de consulta nativo de la fuente de datos. En los casos en que los datos ya están en la memoria, no necesita un proveedor de Linq; Linq 2 Objects está bien. Sin embargo, si está utilizando Linq para hablar con un almacén de datos externo como un DBMS o una nube, es absolutamente esencial.
La premisa básica de cualquier estructura de consulta es que el motor de la fuente de datos debe hacer la mayor parte del trabajo posible y devolver solo los datos que necesita el cliente. Esto se debe a que se supone que la fuente de datos es la que mejor sabe cómo administrar los datos que almacena, y porque el transporte de datos en red es relativamente costoso en términos de tiempo, por lo que debe minimizarse. Ahora, en realidad, esa segunda parte es "devolver solo los datos solicitados por el cliente"; el servidor no puede leer la mente de su programa y saber lo que realmente necesita; solo puede dar lo que se pide. Aquí es donde un proveedor inteligente de Linq absolutamente destruye una implementación "ingenua". Usando el lado IQueryable de Linq, que genera árboles de expresión, un proveedor de Linq puede traducir el árbol de expresión a, por ejemplo, una declaración SQL que el DBMS utilizará para devolver los registros que el cliente está solicitando en la instrucción Linq. Una implementación ingenua requeriría recuperar TODOS los registros usando una declaración SQL amplia, para proporcionar una lista de objetos en memoria al cliente, y luego todo el trabajo de filtrado, agrupamiento, clasificación, etc. lo realiza el cliente.
Por ejemplo, supongamos que estaba utilizando Linq para obtener un registro de una tabla en el DB por su clave principal. Un proveedor de Linq podría traducir dataSource.Query<MyObject>().Where(x=>x.Id == 1234).FirstOrDefault()
en "SELECT TOP 1 * from MyObjectTable WHERE Id = 1234". Eso devuelve cero o uno registros.Una implementación "ingenua" probablemente envíe al servidor la consulta "SELECT * FROM MyObjectTable", luego use el lado IEnumerable de Linq (que funciona en clases en memoria) para hacer el filtrado. En una declaración esperas producir 0-1 resultados de una tabla con 10 millones de registros, ¿cuál de estos crees que harían el trabajo más rápido (o incluso funcionarían sin agotar la memoria)?
No estoy seguro de por qué linq-to-excel se beneficia de IQueryable, pero hay casos en los que hace que el código sea mucho más rápido. – CodesInChaos