2012-01-10 13 views
8

Primero soy un novato en LINQ! Entonces, la cosa es que tengo una colección que:¿Mezclar Any() y First() en LINQ?

  1. no contiene vistas de identificación (cadena)
  2. o contiene sólo una vez

que quería utilizar Dónde pero Don 't como los if instrucciones que tengo que hacer ... así que aquí está mi código:

if (MyCollection.Any(rm => rm.BaseName == rbName)) 
{ 
    var tmp = MyCollection.First(rm => rm.BaseName == rbName); 
} 

esto funciona, pero realmente me siento como esta no es la forma en que debería hacerlo con LINQ ... ¿Alguna sugerencia?

+0

debe marcar 'FirstOrDefault' – V4Vendetta

+0

¿Por qué no utiliza FirstOrDefault(), y después de la consulta comprueba si su resultado es nulo o contiene sus datos? – BigL

+0

no sabía este Método :(Prefiero SingleOrDefault de todos modos! –

Respuesta

16

no única entidad respuesta (con excepción de lanzamiento en varias instancias)

Uso SingleOrDefault. Esto devolverá el elemento único si existe, nulo si no existe o arrojará y la excepción si hay más de uno.

var tmp = MyCollection.SingleOrDefault(rm => rm.BaseName == rbName); 

propiedad única de Respuesta (nunca habrá varias instancias)

Si su sistema está configurado de manera que BaseName es una entidad única, el usuario FirstOrDefault, esto no será una excepción si hay son múltiples, ya que se detendrán en la primera instancia, pero el sistema se diseñará para que nunca haya la misma instancia, por lo que sería aceptable (y reduciría el tiempo).

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName); 
+0

Esto es realmente bueno! El manejo de excepciones es muy agradable :) –

+1

Es agradable de una manera que si alguna vez hay una coincidencia, arrojará una excepción, pero si su sistema está configurado para que no sea posible un duplicado, entonces la excepción nunca será necesaria, luego vaya con FirstOrDefault (solo si es una clave principal o ha configurado la validación al insertarla). – ThePower

5
var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName)); 

Aquí tmp será nula si no tiene dicho registro.

1

Any vuelve a bool indica si tales elementos existen, First devuelve el registro de su colección. Entonces, en cualquier caso, tendrá un objeto de la colección y el resultado de su condición. Puede usar FirstOrDefault y luego verificar null su valor devuelto.

var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName); 
if (tmp != null) 
{ 
    // do something 
} 
2

puede usar,

FirstOrDefault() 

o

SingleOrDefault() 
1
var tmp = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName); 
if (tmp != null) 
{ 
    // Do something 
} 
12

Como dice thepower, se debe utilizar SingleOrDefault o tal vez FirstOrDefault. Si realmente solo hay una entrada de este tipo, harán lo mismo, pero FirstOrDefault puede ser más rápido si usa LINQ to Objects - SingleOrDefault tendría que escanear toda la secuencia para verificar que no haya otras coincidencias .

Si hay varias coincidencias, SingleOrDefault lanzará una excepción; FirstOrDefault simplemente devolverá la primera coincidencia.

Así que es posible utilizar:

var result = MyCollection.FirstOrDefault(rm => rm.BaseName == rbName); 
if (result != null) 
{ 
    // Use it 
} 

Tenga en cuenta que esto puede ser difícil si el tipo de elemento de secuencia es un tipo de valor, ya que no puede ser capaz de distinguir entre el valor predeterminado para el tipo de elemento, debido a no hay coincidencias, y un valor "real". Parece que es poco probable que sea un problema en este caso, pero vale la pena tenerlo en cuenta.

+0

gracias por estas precisiones! :) –

+0

Buen punto Jon. Es difícil ver si era una clave principal o un elemento definido de forma única, una gran adición, sin embargo. – ThePower

Cuestiones relacionadas