In the previous post, my question was about a small change in the code that would yield a big improvement. The answer is:

 image

What changed?

  1. No try / catch
  2. We reversed the order of writes: first we write the details, then we write the “header” or “master” record for the expense.

If the last SaveChanges fails, then there will be orphaned records and images, but the user will not see anything (except for the exception), and presumably would re-enter the expense report. In the meantime a background process will eventually clean up everything. Simple and efficient.