.Net Core Console App - EF Core SaveChangesAsync() not committing updates to database

1.4k Views Asked by At

To test the Data Access Layer of a wider project, I have written a simple console app as a test harness to call the DAL.

The saving of the data is a two-step operation. The first step is to save the very basic information from the report and HAS HAS to be succeed.. The second step is to decipher the raw data into the model and then save it but if this fails, its not a big problem and will be reported and addressed later.

The whole process is to run asynchronously (its part of a REST) but the await _context.SaveChangesAsync() calls do not appear to wait and the app exits and no data is saved.

Below is a simplified example of the DB update

public async Task<bool> SubmitFlightReportAsync(string ReportData)
{
    try
    {
        // Save the primary data - MUST Succeed
        _logger.LogInformation("Saving primary data database ");
        Models.MyReport myRpt = new Models.MyReport()
        {
            Status = 1,
            RawData = ReportData
        };
        _context.MyReports.Add(myRpt);

        if (await _context.SaveChangesAsync() > 0)
        {
            _logger.LogInformation("Primary save complete");

            // Now update with all the extracted data - Optional Succeed
            try
            {
                _logger.LogInformation("Extracting secondary data");
                /*
                 * 
                 * Here is where we extract all the information from the Report Data 
                 * and update the Model, before saving
                 * 
                 */
                _logger.LogInformation("Saving extracted data");

                if (await _context.SaveChangesAsync() > 0)
                {
                    _logger.LogDebug("Secondary save complete");
                }

            }
            catch (Exception ex)
            {
                _logger.LogError("Error saving secondary data ");
            }
        }
        else
        {
            _logger.LogInformation("Primary save failed");
        }
    }
    catch (Exception ex)
    {
        _logger.LogCritcal("Something went horrobly wrong");
    }
}

.and is called from the console app as such...

_logger.LogInformation("Starting application");
_fltSvc.SubmitFlightReportAsync("this is the report data as a string")
_logger.LogInformation("All done");

When I run the app, here's the logging that gets reported...

object:Information: Starting application
object:Information: Saving primary data database

... Where's all the other logging messages?

object:Information: All done

As you can see, it gets to the point of the first SaveChangesAsync, waits a little, as if its doing something, and then jumps back to the main thread..... and NO DATA is saved in the database.

I am sure it's something pretty simple, but I just can see it...

Thanks.

2

There are 2 best solutions below

9
On

When you call to SubmitFlightReportAsync, you initiate the execution of your operation and then return to the caller. When you then end your application immediately, the task will not have a chance to execute. You have to wait for task completion, before you can assume that everything is done:

_logger.LogInformation("Starting application");
Task submitTask =
    Task.Run(() => _fltSvc.SubmitFlightReportAsync("this is the report data as a string"));
submitTask.Wait();
_logger.LogInformation("All done");

In case you are running this code from the Main method and you are using C# 7.0 or higher, you can also simply create an async Main and await in there:

static async void Main() {
    //...
    _logger.LogInformation("Starting application");
    await _fltSvc.SubmitFlightReportAsync("this is the report data as a string")
    _logger.LogInformation("All done");
    //...
}
1
On

Call SubmitFlightReportAsync in your main without await like the following.

public static void Main(string[] args)
{
    Task t = SubmitFlightReportAsync("bla");
    t.Wait(); //This is the line you need to have when working with console apps.
}

Asyny and Await is different while using it in Console app.

Or take a look at the following: async at console app in C#?