I would propose that you create a method, RefreshStudentCourses, or
something like that, and then call it at strategic points throughout
your application.
I find that you usually get cleaner, easier to read, easier to maintain
code by modeling exactly what's going on in real life, rather than
playing tricks behind the scenes.
For example, you could call RefreshFromDatabase(), which in turn calls
RefreshStudentCourses(), every time the user starts a new business
operation, a top-level action.
Another problem with your original solution is that you can't depend
upon your data being self-consistent throughout an entire top-level
operation. Half-way through doing something, you could call your
Course.Students accessor and the list could change, which might put it
out of synch with other data that you've gathered up to that point,
making your top-level operation crash, or, even worse, do subtly wrong
things.
If you have an explicit call to refresh from the database, and call it
at strategic points, you can assume that between those calls your data
will not shift under your feet, which will make your whole program
simpler.