Linq to SQL: .FirstOrDefault () nicht anwendbar, um neue {...} auszuwählen

Ich habe gerade diese Frage gestellt. Was mich zu einer neuen Frage geführt hat :)

Bis zu diesem Punkt habe ich das folgende Muster der Auswahl von Zeug mit Linq zu SQL verwendet, mit dem Zweck, 0 "Zeilen" zu behandeln, die von der Abfrage zurückgegeben werden:

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

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

Aber ich kann FirstOrDefault() nicht verwenden, wenn ich Folgendes mache:

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:

Ich denke, mein Build schlägt fehl, weil ich versuche, das Ergebnis der Abfrage einer Variablen ( this._user ) zuzuweisen, die mit dem Typ [DataContext] .User deklariert ist.

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

Kompilierungsfehler: Der Typ "AnonymousType # 1" kann nicht implizit in "[DataContext] .User" konvertiert werden.

Irgendwelche Gedanken darüber, wie ich das umgehen kann? Müsste ich mein eigenes Objekt machen?

4

5 Antworten

Warum können Sie das Gleiche tun? Gibt es einen Fehler?

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.
}

Es ist immer noch ein Referenzobjekt, genau wie Ihr tatsächliches Objekt, es ist nur anonym, so dass Sie den tatsächlichen Typ nicht kennen, bevor der Code kompiliert wird.

13
hinzugefügt
Meine Frage wurde aktualisiert.
hinzugefügt der Autor roosteronacid, Quelle
Einverstanden, das obige sollte funktionieren, außer es gibt einen nicht verwandten Laufzeitfehler.
hinzugefügt der Autor Codewerks, Quelle

Aktualisierung:

Ich sehe jetzt, was du eigentlich fragst! Entschuldigung, meine Antwort trifft nicht mehr zu. Ich dachte, du würdest keinen Nullwert bekommen, wenn es leer ist. Die akzeptierte Antwort ist korrekt, wenn Sie das Objekt außerhalb des Gültigkeitsbereichs verwenden möchten, müssen Sie einen neuen Typ erstellen und einfach New MyType (...) verwenden. Ich weiß, DevEx RefactorPro hat ein Refactoring dafür, und ich denke, Resharper auch.

Rufen Sie .FirstOrDefault (null) wie folgt auf:

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);

Das macht den Trick für mich.

2
hinzugefügt
if (person.Any()) /* ... */;

ODER

if (person.Count() == 0) /* ... */;
1
hinzugefügt

In Bezug auf Ihr UPDATE: Sie müssen entweder Ihren eigenen Typ erstellen, diesen._Benutzer zu int ändern oder das gesamte Objekt auswählen, nicht nur bestimmte Spalten.

1
hinzugefügt

Sie können weiterhin FirstOrDefault verwenden. Nur haben

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

PersonFields ist NULL oder ein Objekt mit den von Ihnen erstellten Eigenschaften.

0
hinzugefügt