c# - realizar - Sintaxis de los métodos de extensión frente a la sintaxis de la consulta
realizar consultas en c# (7)
Compilan lo mismo, y son equivalentes. Personalmente, prefiero los métodos lambda (extensión) para la mayoría de las cosas, solo usando las declaraciones (estándar) si estoy haciendo LINQ to SQL o intentando simular SQL. Encuentro que los métodos lambda fluyen mejor con el código, mientras que los enunciados distraen visualmente.
Estoy tratando de entender si hay un buen momento para usar palabras clave linq estándar o métodos de extensión linq con expresiones lambda. Parece que hacen lo mismo, simplemente están escritos de manera diferente. ¿Es puramente una cuestión de estilo?
var query = from p in Products
where p.Name.Contains("foo")
orderby c.Name
select p;
// or with extension methods:
var query = Products
.Where(p => p.Name.Contains("foo"))
.OrderBy(p => p.Name);
Son muy similares, con el segundo ejemplo siendo un poco más escueto, pero quizás menos expresivo si no sabes lo que está haciendo el =>.
Además de escribir el código breve, ¿hay otras ventajas de usar los métodos de extensión en comparación con la sintaxis LINQ?
Creo que es una buena idea no usarlos juntos y elegir uno y seguir con él.
Principalmente es un gusto personal, pero en la sintaxis de la consulta (método de comprensión) no todos los operadores están disponibles como se dijo anteriormente.
Encuentro la sintaxis de los Métodos de extensión más en línea con el resto de mi código. Hago mi SQL en SQL. También es muy fácil construir su expresión simplemente agregando todo encima uno del otro con los métodos de extensión.
Solo mis dos centavos.
Como aún no puedo hacer comentarios, quiero hacer uno aquí para la respuesta de la herramienta de programación: ¿Por qué crear un método completamente nuevo para el último ejemplo? No puedes usar:
.Where(user => IDIsBelowNumber(user, 10, true))
Honestamente, a veces puede ser situacional una vez que comienzas a usar Funcs y Actions. Digamos que estás usando estos tres funcs:
Func<DataClasses.User, String> userName = user => user.UserName;
Func<DataClasses.User, Boolean> userIDOverTen = user => user.UserID < 10;
Func<DataClasses.User, Boolean> userIDUnderTen = user => user.UserID > 10;
Como puede ver, el primero reemplaza la expresión lamdba para obtener el nombre de usuario, el segundo reemplaza una expresión lamdba utilizada para verificar si el ID es menor que 10, y seamos sinceros, el tercero debería ser bastante fácil de entender ahora.
NOTA: Este es un ejemplo tonto pero funciona.
var userList =
from user in userList
where userIDOverTen(user)
select userName;
Versus
var otherList =
userList
.Where(IDIsBelowNumber)
.Select(userName)
En este ejemplo, el segundo es un poco menos detallado ya que el método de extensión puede hacer un uso completo del Func, pero la expresión Linq no puede, ya que se ve solo por un booleano en lugar de un Func que devuelve booleano. Sin embargo, aquí es donde podría ser mejor usar el lenguaje de expresión. Supongamos que ya tiene un método que abarca más que solo un usuario:
private Boolean IDIsBelowNumber(DataClasses.User user,
Int32 someNumber, Boolean doSomething)
{
return user.UserID < someNumber;
}
Nota: doSomething está allí simplemente porque el método de extensión where está bien con un método que toma un usuario y un entero y devuelve booleano. Algo molesto para este ejemplo.
Ahora, si miras la consulta de Linq:
var completeList =
from user in userList
where IDIsBelowNumber(user, 10, true)
select userName;
Eres bueno para eso. Ahora el método de extensión:
var otherList =
userList
.Where(IDIsBelowNumber????)
.Select(userName)
Sin una expresión lambda, realmente no puedo llamar a ese método. Entonces, ahora lo que tengo que hacer es crear un método que cree un Func basado en la llamada al método original.
private Func<DataClasses.User, Boolean> IDIsBelowNumberFunc(Int32 number)
{
return user => IDIsBelowNumber(user, number, true);
}
Y luego enchúfalo:
var otherList =
userList
.Where(IDIsBelowNumberFunc(10))
.Select(userName)
Como puede ver, a veces puede ser más fácil usar el enfoque de consulta a veces.
Me gusta utilizar la sintaxis de consulta cuando realmente es una consulta, es decir, una expresión lenta que evalúa según demanda.
Un método que se parece a las llamadas a métodos regulares (sintaxis de método o sintaxis lambda) no se ve lo suficientemente flojo, así que lo uso como una convención. Por ejemplo,
var query = from p in Products
where p.Name.Contains("foo")
orderby p.Name
select p;
var result = query.ToList(); //extension method syntax
Si no es una consulta, me gusta el estilo fluido que me parece consistente con otras llamadas que ejecutan con entusiasmo.
var nonQuery = Products.Where(p => p.Name.Contains("foo"))
.OrderBy(p => p.Name)
.ToList();
Me ayuda a diferenciar mejor los dos estilos de llamadas. Por supuesto, hay situaciones en las que se verá obligado a utilizar la sintaxis del método de todos modos, por lo que mi convención no es lo suficientemente convincente.
Prefiero la sintaxis del método de extensión cuando uso métodos Linq que no tienen equivalente de sintaxis de consulta, como FirstOrDefault () u otros como ese.
Una ventaja de los métodos de extensión / expresiones lynda es los operadores adicionales que se ofrecen como Skip y Take. Por ejemplo, si está creando un método de paginación, puede omitir los primeros 10 registros y tomar los siguientes 10 y es fácil de implementar.
Una ventaja del uso de los métodos de extensión LINQ ( consultas basadas en métodos) es que puede definir métodos de extensión personalizados y aún así leer bien.
Por otro lado, cuando se utiliza una expresión de consulta LINQ, el método de extensión personalizado no está en la lista de palabras clave. Se verá un poco extraño mezclado con las otras palabras clave.
Ejemplo
Estoy usando un método de extensión personalizado llamado Into
cual solo toma una cadena:
Ejemplo con consulta
var query = (from p in Products
where p.Name.Contains("foo")
orderby c.Name
select p).Into("MyTable");
Ejemplo con métodos de extensión
var query = Products
.Where(p => p.Name.Contains("foo"))
.OrderBy(p => p.Name)
.Into("MyTable");
En mi opinión, este último, utilizando una consulta basada en el método , se lee mejor cuando tienes métodos de extensión personalizados.