0

I'm creating an application which automatically update the database structure is case that database is out of data. Let's call it UpdateApp. That application is invoked by another application which using EntityFramework to access MySql server. This application is the MainApp. Because it takes a long time to perform the update process, so the main idea is just call update structure when an error (such as no table or no field defined, ...) occurs in the MainApp.

Then, I'd like to make sure my UpdateApp has updated database successfully. Therefore, I want to have the query which causes that error in MainApp before updating and run it again. I try to run debug to find if there is any field in exception objects contains the query, but still cannot find out anything.

try {
    using (DbContext ctx = ContextManager.CreateContext()) {
        // Do something, for example, get value from database
    }
} catch (EntityException ex) {
    if (ex.InnerException is MySqlException) {
        // 1. Handle update structure, call the UpdateApp here
        // 2. Try to get the query and run it again <= I get stuck here
    }
}
Taylan Aydinli
  • 4,333
  • 15
  • 39
  • 33
Tu Tran
  • 1,957
  • 1
  • 27
  • 50
  • 1
    This sounds...interesting...what if the query you want to re-run isn't a query? What if it's an update or delete? And what if that update or delete was part of a transaction containing other statements that were supposed to run before or after the one that failed? – Colin Dec 05 '13 at 10:57
  • @Colin: Good question. I try to handle the query first, because it's simplest. I'll update it to handle more later, when this stuck is resolved. – Tu Tran Dec 05 '13 at 11:01
  • 1
    How about logging errors on the database side? – S_F Dec 05 '13 at 11:20
  • @S_F: To do that, I must have right permission and correct argument for accessing the log file. Thus, it's not a good way to do. – Tu Tran Dec 05 '13 at 14:33

1 Answers1

1

Assuming MySqlException works the same way as SqlException you cannot get to the SqlCommand via the exception. But surely what you ought to do is re-run the entire operation that failed? Like this:

using (DbContext ctx = ContextManager.CreateContext())
{
   try
   {
      DoSomethingForExampleGetValueFromDatabase(DbContext ctx)
   }
   catch (EntityException ex)
   {
       if (ex.InnerException is MySqlException) 
       {
           // 1. Handle update structure, call the UpdateApp here
           DoSomethingForExampleGetValueFromDatabase(DbContext ctx)
       }
   }
}

private method DoSomethingForExampleGetValueFromDatabase(DbContext ctx)
{
}

References:

Obtain the Query/CommandText that caused a SQLException

Community
  • 1
  • 1
Colin
  • 22,328
  • 17
  • 103
  • 197
  • In current design, I have to re-invoke the whole method, it looks like what you're recommending here. I need this feature more efficient, because I'll show user if the database has been updated successfully or not. – Tu Tran Dec 05 '13 at 14:37
  • I cannot get my head around why you would wait until a user is trying to do something, then let it fail before you trigger an update to a database schema. Why isn't the database updated at the same time as the app? Or why not implement database versioning as part of the update so that the need to update can be detected without running code that might fail? – Colin Dec 05 '13 at 14:49
  • As I mentioned in the question, the task which check & update database take a long time. In addition, that task is rare to be invoked. Therefore, I don't want to make user wait at the time **MainApp** started. Regarding database version, it's not as efficient as compare database structure. Thus, I prefer the second method. – Tu Tran Dec 05 '13 at 15:12