As I see it, ViewData (and its relatives, such as ViewBag, Model, etc.) are for the current current view . Your _Layout.cshtml is not relevant to the current view; and it would be inconvenient if EVERY controller had to transmit category data in addition to all the other data that it needs to transmit for presentation.
Instead, I provide a static method in one of my helper classes that extracts categories from a database. I also do some caching there, so I don’t have to hit the DB with every single request. Then _Layout.cshtml just calls this static method. Simple and elegant.
If you want, you can bring it to a partial view, make it an auxiliary method, whatever.
However, one note - in my custom error view, the same _Layout.cshtml is also used, and if the database goes down, you get an exception trying to display the exception. ASP.NET MVC is smart enough to detect this and interrupt processing, but you left the default error page. What I did was to place try...catch around these dangerous calls that silently ignore the exception if the current page is the kind of error.
Vilx-
source share