The principal performance issues are on the database side (or maybe you could do some kind of caching or pre-loading), but your code could be made much clearer and shorter (there should be also some minor performance improvements):
string[] columnNames = new[] { "sub_id", "sibheadername" };
var categories = db.allcategories().ToList();
if (categories.Count == 0)
{
return;
}
var dt = new DataTable();
dt.Columns.Add(columnNames[0]);
dt.Columns.Add(columnNames[1]);
foreach (var category in categories)
{
var selectedCategories = db.selcategories(Convert.ToInt32(category.sub_id)).ToList();
int count = Convert.ToInt32(selectedCategories.First().Column1);
DataRow dr = dt.NewRow();
dr[0] = category.sub_id;
dr[1] = count != 0
? category.sibheadername + " (" + count + ")" // btw. this is FASTER (in this case) than a StringBuilder!
: category.sibheadername;
dt.Rows.Add(dr);
}
areaDropdown.DataSource = dt;
areaDropdown.DataTextField = columnNames[1];
areaDropdown.DataValueField = columnNames[0];
areaDropdown.DataBind();
areaDropdown.Items.Insert(0, "");