public async Task <CourseDetailViewModel> GetCourseAsync(int id) { logger.LogInformation("Course {id} requested", id); //permette di filtrare i log in base al valore degli id //la prima query carica il corso scelto al rispettivo id, la seconda invece carica tutte le lezioni legate all'id di quel corso //FormattableString separa la parte fissa dai suoi parametri FormattableString query = $@"SELECT Id, Title, Description, ImagePath, Author, Rating, FullPrice_Amount, FullPrice_Currency, CurrentPrice_Amount, CurrentPrice_Currency FROM Courses WHERE Id={id} ; SELECT Id, Title, Description, Duration FROM Lessons WHERE CourseID={id}"; DataSet dataSet = await db.ExecuteQueryAsync(query); //Course: //estrae i dati dalla prima datatable, se Rows >1 allora c'é un errore in quanto ci può essere solo 1 Row (evita la SqlInjection) var courseTable = dataSet.Tables[0]; if (courseTable.Rows.Count != 1) { logger.LogWarning("Course {id} not found", id); //messaggio di log, problema non grave throw new CourseNotFoundException(id); } var courseRow = courseTable.Rows[0]; //leggiamo la riga (courseRow), la passiamo a FromDataRow che farà la mappatura tra il datarow restituendo un oggetto di tipo courseDetailViewModel var courseDetailViewModel = CourseDetailViewModel.FromDataRow(courseRow); //Lessons var lessonDataTable = dataSet.Tables[1]; foreach (DataRow lessonRow in lessonDataTable.Rows) { LessonViewModel lessonViewModel = LessonViewModel.FromDataRow(lessonRow); courseDetailViewModel.Lessons.Add(lessonViewModel); //ogni oggetto di LessonViewModel trovato viene aggiunto alla lista } return(courseDetailViewModel); }