2016-12-25 3 views
0

Ich bin neu zu verwenden, warten/async und ich habe eine grundlegende Frage. Ich konnte das Warten/Async-Modell in meinem WebApi-Controller und das Business-Objekt (BL) erfolgreich für Löschungen so in der BL auf der Delete Methode ich aufrufen await entities.SaveChangesAsync(); und aktualisiert die Signatur der Methode, um public static async Task<ProfileItem> Delete(int profileId, int profileItemId) zurückzukehren und dies funktioniert !!!C# GetAwaiter async Aufgabe <T>

Jetzt möchte ich das gleiche tun, wenn ich Daten „holen“, so, ich habe ein „Getter“ und ich die Methode der Signatur public static async Task<List<Property>> GetProperties(int userId, int userTypeId) aktualisieren und hier habe ich einige Logik, die (1) verwendet die Entity Framework eine Ergebnismenge abrufen, dann mache ich ein paar Sachen und konvertiere mein EntityObject in ein BusinessObject und gebe eine List<Property> zurück, aber wenn ich return await ... mache, erhalte ich den Fehler: Liste enthält keine Definition für 'GetAwaiter' und keine Erweiterungsmethode ...

Hier ist der Code

public static async Task<List<Property>> GetProperties(int userId, int userTypeId) 
    { 

     entities = new MyEntities(); 

     var userType = entities.sl_USER_TYPE.Where(_userType => _userType.ID == userTypeId).First(); 


     var properties = entities.sl_PROPERTY.Where(_property => _property.USER_ID == userId && _property.USER_TYPE_ID == userTypeId); 

     if (!properties.Any()) 
      throw new Exception("Error: No Properties exist for this user!"); 

     // here is where I get the error 
     return await ConvertEntiesToBusinessObj(properties.ToList(), userId); 

    } 

Was muss ich tun, um in der Lage sein das sein zugreifen Funktionen dieser Funktion in diesem Fall. Grundsätzlich kann ich Task/async zum Speichern von Informationen in der DB verwenden aber nicht bekommen. Ich bin sicher, es ist mein Mangel an Verständnis.

Danke.

+2

Das Problem in 'ConvertEntiesToBusinessObj' ist zeigen Sie den Code für diese Methode – CodingYoshi

+3

' var list = erwarten properties.ToListAsync();... if (list.Count == 0) { Neue Exception auslösen ("Fehler: Für diesen Benutzer sind keine Eigenschaften vorhanden!");} else {return ConvertEntiesToBusinessObj (list, userId);} '. Wenn Sie Elemente trotzdem abrufen, müssen Sie' Any() 'nicht trennen Sie können auch 'awarate FirstAsync()' anstelle von 'First()' verwenden. – PetSerAl

Antwort

3

Sie können await nur auf "abwarts" verwenden, was in den meisten Fällen Task oder Task<T> bedeutet.

ConvertEntiesToBusinessObj gibt Task<T> nicht zurück, was in Ordnung ist. Es klingt wie eine synchrone Methode, also sollte es nicht.

Was möchten Sie tun, ist die Verwendung ToListAsync statt ToList und await, die:

return ConvertEntiesToBusinessObj(await properties.ToListAsync(), userId); 

Auch als PetSerAI wies darauf hin, es effizienter wäre ToListAsync einmal zu verwenden, anstatt Any gefolgt von ToList/ToListAsync:

public static async Task<List<Property>> GetProperties(int userId, int userTypeId) 
{ 
    entities = new MyEntities(); 
    var userType = await entities.sl_USER_TYPE.Where(_userType => _userType.ID == userTypeId).FirstAsync(); 
    var properties = await entities.sl_PROPERTY.Where(_property => _property.USER_ID == userId && _property.USER_TYPE_ID == userTypeId).ToListAsync(); 

    if (!properties.Any()) 
    throw new Exception("Error: No Properties exist for this user!"); 

    return ConvertEntiesToBusinessObj(properties, userId); 
} 

Die allgemeine Regel hier zu folgen ist zu nicht Ansatz async mit der Denkweise von "Ich möchte diese Funktion async machen; Wie mache ich das? ". Der geeignete Ansatz besteht darin, zuerst natürlich-asynchrone Operationen (im Allgemeinen I/O-basiert) zu identifizieren - in diesem Beispiel die EF-Abfragen. Dann machen Sie diese asynchron und rufen Sie sie mit await, und erlauben async/await natürlich von dort wachsen