In the previous post, my question was about a small change in the code that would yield a big improvement. The answer is:
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.