The solution for this issue was presented in the comments, so I'm writing it up here for completeness.
ORIGINAL CODE:
var rootDrive = await GraphClient.Users[UserId].Drive.Request().GetAsync();
This returns the metadata of the user's OneDrive, but does not capture the Children. We will need this information later, however, so the final solution uses both this reference and the updated code.
UPDATED CODE:
To do that, you need to reference the drive's Root and its Children:
var driveItems = await GraphClient.Users[UserId].Drive
.Root
.Children
.Request()
.GetAsync();
Doing so returns an IDriveItemChildrenCollectionPage:

PROCESS THE CHILDREN:
For small samples, a standard foreach will work fine, but for larger collections you will need to implement a PageIterator (which I have not done yet). To get the children of this driveItem, you will need the drive Id of the root element as well as the current driveItem.Id:
var children = await GraphClient.Drives[rootDriveId].Items[item.Id].Children.Request().GetAsync()
Putting it altogether, it looks something like this:
public async Task ListOneDrive()
{
var rootDrive = await GraphClient.Users[UserId].Drive.Request().GetAsync();
var driveItems = await GraphClient.Users[UserId].Drive
.Root
.Children
.Request()
.GetAsync();
foreach (var item in driveItems)
{
await ListDriveItem(rootDrive.Id, item);
}
}
public async Task ListDriveItem(string rootDriveId, DriveItem item, int indentLevel = 1)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < indentLevel; i++)
{
sb.Append($" ");
}
if (item.Folder != null)
{
Console.WriteLine($"{sb.ToString()}> {item.Name}/");
var children = await GraphClient.Drives[rootDriveId].Items[item.Id].Children.Request().GetAsync();
foreach (var child in children)
{
await (ListDriveItem(rootDriveId, child, indentLevel + 1));
}
}
else if (item.File != null)
{
Console.WriteLine($"{sb.ToString()} {item.Name}");
}
}
This example is from a Console app that uses a recursive call to drill down through all the folders. Both methods really should have a PageIterator as mentioned above.
Update as of Microsoft.Graph 5.12.0
var driveItem = await graphClient.Me.Drive.GetAsync();
var driveItems = await graphClient.Drives[driveItem.Id].Items["root"].Children.GetAsync();
foreach (var item in driveItems.Value)
{
await ListDriveItem(driveItem.Id, item);
}
and then for ListDriveItem function:
public async Task ListDriveItem(string rootDriveId, DriveItem item, int indentLevel = 1)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < indentLevel; i++)
{
sb.Append($" ");
}
if (item.Folder != null)
{
Console.WriteLine($"{sb.ToString()}> {item.Name}/");
var children = await graphClient.Drives[rootDriveId].Items[item.Id].Children.GetAsync();
foreach (var child in children.Value)
{
await (ListDriveItem(rootDriveId, child, indentLevel + 1));
}
}
else if (item.FileObject != null)
{
Console.WriteLine($"{sb.ToString()} {item.Name}");
}
}