Simple ASP.NET C# class design Here's a class I'm designing:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;

namespace Artworking.classes
{

    // A group permission level
    public class PermissionGroup
    {
        public int ID;                  // Unique ID for this group
        public bool hasFullControl;     // Does this group have complete control
        public user creator;            // Who created this group
        public string groupName;        // Reference name for group

        // Constructor for when a permission group ID is passed
        public PermissionGroup(SqlConnection cn, int ID)
        {
            using (SqlCommand cmd = new SqlCommand("SELECT creatorUserID, group_name, fullControl FROM tblATPermissionGroups WHERE ID = " + ID, cn))
            {
                SqlDataReader rdr = cmd.ExecuteReader();
                if (rdr.Read())
                {
                    this.creator.ID = int.Parse(rdr["creatorUserID"].ToString());
                    this.groupName = rdr["group_name"].ToString();
                    this.hasFullControl = bool.Parse(rdr["fullControl"].ToString());
                }
                rdr.Close();
            }
        }
    }

}


Am I on the right track?  Please note I'm not using the built in authentication as it needs to be backwards compatible for an old system. What I'm just checking is that I'm handling these classes properly and loading the data in correctly etc.  As I understand it I'm meant to put my SQL commands in the classes and away from the actual pages right?
It is generally not a good idea to do this type of processing in the .ctor.  Move it to a Load (or some such name) method.  This however means your object is not really loaded after instantiated which is another issue.  As such, I would recommend separating the entity information (HasFullControl, Creator, GroupName, etc) type from the type that loads the information from the database.  You could change PermissionGroup type to just have the data properties and then move the loading logic to a data layer that is responsible for creating the instance a loading the data.

Concatenating text to the end of a sql string leaves you open to Sql Injection attacks (though not in this specific case).  Use a parameter instead:  

using (SqlCommand cmd = new SqlCommand("SELECT creatorUserID, group_name, 
    fullControl FROM tblATPermissionGroups WHERE ID = @id", cn))
{
    cmd.Parameters.AddWithValue("@id", id);
    ...
}


You need to wrap the SqlDataReader in a using block.

Use public readonly properties rather than public fields.

Consider using a IDbConnection rather than SqlConnection.  Doing so will allow you to more easily mock the data call when testing this method and makes it easier to support other RDBMS's should the need arise.

Throw helpful exceptions if something goes wrong when populating the data fields.

Follow the .Net Framework naming guidelines