For this, you can have a table where an item can reference its parent, if any.

If the ParentId
column is NULL
, the category is a root one. If not, the parent is referenced.
You can then find the subcategories of a category by walking through the table and searching for items with ParentId
equal to Id
of the category.
Note that ParentId
must be indexed for better performance, and that there must be a foreign key of ParentId
to Id
to ensure the validity of your data.
Storing recursively the categories:
private void SaveCategoryRecursively(Category category)
{
foreach (var subCategory in category.SubCategories)
{
query(@"
insert into [dbo].[Categories] ([Id], [ParentId], ...)
values (@id, @parentId, ...)", ...);
this.SaveCategoryRecursively(subCategory);
}
}
public void SaveCategories(IEnumerable<Category> rootCategories)
{
foreach (var category in rootCategories)
{
query(@"
insert into [dbo].[Categories] ([Id], [ParentId], ...)
values (@id, NULL, ...)", ...);
this.SaveCategoryRecursively(category);
}
}