2016-12-25 3 views
0

Я новичок в использовании await/async, и у меня есть основной вопрос. Я смог успешно реализовать модель await/async в своем контроллере WebApi и бизнес-объекте (BL) для удалений в BL по методу Delete. Я вызываю await entities.SaveChangesAsync(); и обновляю подпись метода для возврата public static async Task<ProfileItem> Delete(int profileId, int profileItemId), и это работает !!!C# GetAwaiter async Задача <T>

Теперь я хочу сделать то же самое, когда я «получаю» данные, поэтому у меня есть «getter», и я обновляю сигнатуру метода до public static async Task<List<Property>> GetProperties(int userId, int userTypeId), и здесь у меня есть логика, что (1) использует структуру сущности для получить набор результатов, затем я делаю некоторые вещи и конвертирую EntityObject в объект BusinessObject и возвращаю List<Property>, однако когда я делаю return await ..., я получаю сообщение об ошибке: List не содержит определения для GetAwaiter и не использует метод расширения ...

Вот код

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

    } 

Что мне нужно сделать, чтобы быть в состоянии получить доступ к Ве в этом случае это функциональность. В основном я могу использовать Task/async для сохранения информации в БД, но не получения. Я уверен, что это мое отсутствие понимания.

Спасибо.

+2

вопрос находится в 'ConvertEntiesToBusinessObj' Пожалуйста, покажите код для этого метода – CodingYoshi

+3

' списка вара = ждет properties.ToListAsync();... если (list.Count == 0) { throw new Exception («Ошибка: нет никаких свойств для этого пользователя!»);} else {return ConvertEntiesToBusinessObj (list, userId);} '. Если вы все равно будете извлекать элементы, тогда не нужно делать отдельный' Any() ' call. Кроме того, вы можете использовать 'await FirstAsync()' вместо 'First()'. – PetSerAl

ответ

3

Вы можете использовать только await на "awaitables", который по большей части означает Task или Task<T>.

ConvertEntiesToBusinessObj не возвращается Task<T>, что хорошо. Это звучит как синхронный метод, поэтому он не должен.

То, что вы хотите сделать, это использовать ToListAsync вместо ToList и await что:

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

Кроме того, как PetSerAI отметил, что было бы более эффективно использовать ToListAsync один раз, а не Any следуют 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); 
} 

общее правило следовать здесь, чтобы не подходит async с мышлением «Я хочу сделать эту функцию асинхронной; как это сделать? ». Соответствующий подход состоит в том, чтобы сначала определить естественно-асинхронные операции (как правило, на основе ввода-вывода) - в этом примере - запросы EF. Затем сделайте такими асинхронными и вызовите их с await и разрешите async/await расти естественно оттуда

Смежные вопросы