usar sintaxis program curso consultas c# .net linq reusability

sintaxis - usar linq en c#



Reutilización de una consulta LINQ (4)

No se trata de la reutilización de un resultado, sino más de la declaración en sí misma. Tampoco se trata de un error al usar var como se menciona en: LINQ to SQL: reutilizar la expresión lambda

Por pura curiosidad me preguntaba si es posible reutilizar una sola declaración LINQ.

Digamos que tengo la siguiente declaración LINQ:

.Where(x => x.Contains(""));

¿Es posible extraer la declaración x => x.Contains("") y usar algún tipo de referencia para su uso posterior en, digamos, otra clase?

Así que puedo llamarlo así: .Where(previouslySavedStatement);


Depende. Hay dos métodos Where , Enumerable.Where y Queryable.Where . Si está aplicando el .Where a un IEnumerable que no se llama al primero, si lo está aplicando a un IQueryable se llama al segundo.

Dado que Enumerable.Where in a Func , no es reutilizable. Como Queryable.Where toma una expresión, es reutilizable. Puedes hacerlo de la siguiente manera:

var x = new List<string>().AsQueryable(); var query = x.Where (n => n.Contains("some string")); //Extract the lambda clause var expr = query.Expression; var methodExpr = (MethodCallExpression)expr; var quoteExpr = (UnaryExpression)methodExpr.Arguments[1]; var funcExpr = (Expression<Func<string, bool>>)quoteExpr.Operand;

A continuación, puede volver a aplicar la expresión where:

var query2 = x.Where(funcExpr);


Escribí una biblioteca para abordar exactamente esta preocupación, se llama CLink y puede encontrar una implementación para EntityFramework aquí: https://www.nuget.org/packages/CLinq.EntityFramework

Permite crear fragmentos de consulta y usarlos en todas partes en una consulta de linq. Siguiendo el ejemplo de Hamid, crea la siguiente expresión:

System.Linq.Expressions.Expression<Func<Foo, bool>> selector = x => x.Contains("");

Ahora puede usar esta consulta en todas las consultas de linq como esta:

query.AsComposable().Where(o => selector.Pass(o));

Además de este simple ejemplo, también puedes combinar tus fragmentos de consulta:

query.AsComposable().Where(o => selector.Pass(o) || anotherSelector.Pass(o));

o incluso combinarlos juntos:

query.AsComposable().Where(o => anotherSelector.Pass(selector.Pass(o)));

Hay algunas características más, pero creo que es realmente útil, así que compruébalo :)


Puedes almacenarlo en una variable. Si está trabajando con IQueryable , utilice:

System.Linq.Expressions.Expression<Func<Foo, bool>> selector = x => x.Contains("");

Si usa IEnumerable , use:

Func<Foo, bool> selector = x => x.Contains("");

Y úsalo en tu consulta:

query.Where(selector);


Sí, puede escribir una función que contenga la consulta que desea reutilizar, que toma y devuelve un IQueryable <T>

public IQueryable<T> ContainsEmpty(IQueryable<T> query) { return query.Where(x => x.Contains("")); }

Ahora puedes reutilizarlo:

query1 = ContainsEmpty(query1); query2 = ContainsEmpty(another);