When using AutoGenerateColumns=True you can change the header texts of columns by using AS sql operator in your select statement (as you already suggested).
Although in general avoid using AutoGenerateColumns=True, because its inflexible. As you pointed out you get stuck by easy things such as hiding one column.
And here is an example how to hide ID column by using RowDataBound
event
protected void rowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
for (int i = 0; i < e.Row.Controls.Count; i++)
{
var headerCell = e.Row.Controls[i] as DataControlFieldHeaderCell;
if (headerCell != null)
{
if (headerCell.Text == "name_of_id_column")
{
headerCell.Visible = false;
Page.Items["IDCellIndex"] = i;
break;
}
}
}
}
else if (e.Row.RowType == DataControlRowType.DataRow || e.Row.RowType == DataControlRowType.Footer)
{
int idCellIndex = Convert.ToInt32(Page.Items["IDCellIndex"]);
e.Row.Controls[idCellIndex].Visible = false;
}
}