Linq a SQL: .FirstOrDefault () no aplicable para seleccionar nuevo {...}

Acabo de formular esta pregunta . Lo que me llevó a una nueva pregunta :)

Hasta este punto, he utilizado el siguiente patrón de selección de cosas con Linq a SQL, con el fin de poder manejar 0 "filas" devueltas por la consulta:

var person = (from p in [DataContextObject].Persons
              where p.PersonsID == 1
              select new p).FirstOrDefault();

if (person == null)
{
   //handle 0 "rows" returned.
}

Pero no puedo usar FirstOrDefault() cuando lo hago:

var person = from p in [DataContextObject].Persons
             where p.PersonsID == 1
             select new { p.PersonsID, p.PersonsAdress, p.PersonsZipcode };

// Under the hood, this pattern generates a query which selects specific
// columns which will be faster than selecting all columns as the above
// snippet of code does. This results in a performance-boost on large tables.

How do I check for 0 "rows" returned by the query, using the second pattern?



UPDATE:

Creo que mi compilación falla porque estoy tratando de asignar el resultado de la consulta a una variable ( this._user ) declarada con el tipo de [DataContext] .User .

this._user = (from u in [DataContextObject].Users
              where u.UsersID == [Int32]
              select new { u.UsersID }).FirstOrDefault();

Error de compilación: no se puede convertir implícitamente el tipo "AnonymousType # 1" en "[DataContext] .User".

¿Alguna idea sobre cómo puedo evitar esto? ¿Tendría que hacer mi propio objeto?

4

5 Respuestas

¿Por qué puedes seguir haciendo lo mismo? ¿Te está dando un error?

var person = (from p in [DataContextObject].Persons
              where p.PersonsID == 1
              select new { p.PersonsID, p.PersonsAdress, p.PersonsZipcode }).FirstOrDefault();

if (person == null) {    
   //handle 0 "rows" returned.
}

Sigue siendo un objeto de referencia como su objeto real, es simplemente anónimo, por lo que no conoce el tipo real antes de compilar el código.

13
agregado
Actualizado mi pregunta.
agregado el autor roosteronacid, fuente
De acuerdo, lo anterior debería funcionar, a menos que haya un error de tiempo de ejecución no relacionado.
agregado el autor Codewerks, fuente

Actualización:

¡Ahora veo lo que estabas en realidad preguntando! Lo siento, mi respuesta ya no se aplica. Pensé que no obtendría un valor nulo cuando estaba vacío. La respuesta aceptada es correcta, si desea usar el objeto fuera del alcance, debe crear un nuevo tipo y simplemente usar New MyType (...). Sé que RefactorPro de DevEx tiene una refactorización para esto, y creo que también lo hace el resharper.

Llame a .FirstOrDefault (null) de esta manera:

string[] names = { "jim", "jane", "joe", "john", "jeremy", "jebus" };
var person = (
    from p in names where p.StartsWith("notpresent") select 
        new { Name=p, FirstLetter=p.Substring(0,1) } 
    )
    .DefaultIfEmpty(null)
    .FirstOrDefault();

MessageBox.Show(person==null?"person was null":person.Name + "/" + person.FirstLetter);

Eso hace el truco para mí.

2
agregado
if (person.Any()) /* ... */;

O

if (person.Count() == 0) /* ... */;
1
agregado

En cuanto a su ACTUALIZACIÓN: debe crear su propio tipo, cambiar this._user para que sea int , o seleccionar el objeto completo, no solo las columnas específicas.

1
agregado

Todavía puede usar FirstOrDefault . Solo tienes

var PersonFields = (...).FirstOrDefault()  

PersonFields será nulo o un objeto con esas propiedades que ha creado.

0
agregado