I'm trying to create a handler that first of all creates a "mdf" file, which I later connect to. Then I can add tables from a type, that gets all its properties and values. So a class with 2 properties, example:

class Person { String Name { get; set; } float Age { get; set; }

will become:

"CREATE TABLE Person (Name text, Age float)"

and then I add a SQLDataAdapter that gets all it properties and creates functions for Fill, Update, Insert, Delete with one of the Properties as PrimaryKey for the Class/ObjectType.

I'm stuck and I have no idea if I'm thinking the right way, I can create a mdf file but then later when I delete the file data is still somehow present (or something's wrong).

If there's anyone who could give me a hint as to how to think or explain what I'm missing or need to think about.

DataAccess creates a dataset, whenever I add a Table I create a table in the Dataset with the same properties (columns), and I add a SqlDataAdapter for that specific type with methods to Fill/Update/Delete/Insert etc...

And DataAccess method Fill calls the adapter with the DataTable that corresponds to it, but it doesn't work.

Here's my code, if someone could try it out and give me some hints or tell me what I'm thinking wrong:

DataAccess Class:

public class DataAccess
{

    protected String CONNECTION_STRING = "";

    protected DataSet DBSet;
    protected List<object> DBAdapters;

    protected String DatabaseName;

    public DataAccess(String dbName)
    {
        if (!File.Exists(Directory.GetCurrentDirectory() + "\\" + dbName + ".mdf"))
        {
            CreateDatabaseFile(Directory.GetCurrentDirectory() + "\\" + dbName + ".mdf");
        }

        CONNECTION_STRING = "Data Source=.\\SQLEXPRESS;Initial Catalog=tempdb; Integrated Security=true;User Instance=True;";
        DatabaseName = dbName;

        DBSet = new DataSet(dbName);
        DBAdapters = new List<object>();
    }

    public DataTable Fill<T>()
    {

        for (int i = 0; i < DBAdapters.Count; i++)
        {
            try
            {

                if (((DatabaseAdapter<T>)DBAdapters[i]).ObjectType == typeof(T))
                {
                    for (int t=0; t < DBSet.Tables.Count; t++)
                    {
                        if (DBSet.Tables[t].TableName == typeof(T).Name)
                        {
                            ((DatabaseAdapter<T>)DBAdapters[i]).Fill(DBSet.Tables[t]);
                            return (DBSet.Tables[t]);
                        }
                    }
                }
            }
            catch { }
        }

        throw new Exception("Not found");
    }

    public void Insert<T>(T obj)
    {
        object[] values;

        for (int i = 0; i < DBAdapters.Count; i++)
        {
            try
            {

                MessageBox.Show(((DatabaseAdapter<T>)DBAdapters[i]).ObjectType + " == " + typeof(T));

                if (((DatabaseAdapter<T>)DBAdapters[i]).ObjectType == typeof(T))
                {
                    PropertyInfo[] pi = typeof(T).GetProperties();
                    values = new object[pi.Length];

                    for (int p = 0; p < pi.Length; p++)
                    {
                        values[p] = obj.GetType().GetProperty(pi[i].Name).GetValue(obj, null);
                    }

                    ((DatabaseAdapter<T>)DBAdapters[i]).Insert(values);
                }
            }
            catch { throw new Exception("Type not found"); }
        }

        throw new Exception("Not found");
    }

    public int NumOfRows<T>()
    {

        int count = 0;

        if (TableExists(typeof(T).Name))
        {

            using (var connection = new SqlConnection(CONNECTION_STRING))
            {
                using (var command = connection.CreateCommand())
                {
                    command.CommandText = "SELECT * FROM " + typeof(T).Name;
                    var reader = command.ExecuteReader();

                    while (reader.Read())
                    {
                        count++;
                    }

                }
            }
        }

        return count;
    }

    public bool TableExists(String tableName)
    {

        bool exists = false;

        using (var connection = new SqlConnection(CONNECTION_STRING))
        {
            connection.Open();

            using (var command = connection.CreateCommand())
            {

                command.CommandText = "SELECT * FROM INFORMATION_SCHEMA.TABLES";

                using (var reader = command.ExecuteReader())
                {

                    while (reader.Read())
                    {
                        for (int i = 0; i < reader.FieldCount; i++)
                        {
                            if (reader.GetName(i) == "TABLE_NAME")
                            {
                                if (reader.GetValue(i).ToString() == tableName)
                                {
                                    exists = true;
                                }
                            }
                        }
                    }

                }
            }

        }

        return exists;
    }

    private bool Query(String query)
    {

        using (var connection = new SqlConnection(CONNECTION_STRING))
        {
            connection.Open();

            using (var command = connection.CreateCommand())
            {

                command.CommandText = query;

                try
                {
                    command.ExecuteNonQuery();
                }
                catch { return false; }

            }
        }

        return true;

    }

    public void CreateTable<T>(String primaryKey, bool deleteIfExists = true)
    {

        if (TableExists(typeof(T).Name))
        {
            MessageBox.Show("HEJ");
            if (deleteIfExists)
            {
                Query("DROP TABLE " + typeof(T).Name);
            }
            else
            {
                return;
            }
        }

        using (var connection = new SqlConnection(CONNECTION_STRING))
        {
            connection.Open();

            using (var command = connection.CreateCommand())
            {

                String fields = "";

                PropertyInfo[] pi = typeof(T).GetProperties();

                for (int i = 0; i < pi.Length; i++)
                {
                    fields += pi[i].Name + " " + GetDBType(pi[i].PropertyType).ToString() + ", ";
                }

                command.CommandText = String.Format("CREATE TABLE {0} ({1})", typeof(T).Name, fields.Substring(0, fields.Length - 2));
                command.ExecuteNonQuery();

                try
                {
                    DBSet.Tables.Add(CreateDataTable<T>());
                    DBAdapters.Add(CreateDataAdapter<T>(primaryKey));
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }

            }

            connection.Close();

        }
    }

    private void CreateDatabaseFile(String filename)
    {

        String dbName = System.IO.Path.GetFileNameWithoutExtension(filename);

        using (var connection = new SqlConnection("Data Source=.\\SQLEXPRESS;Initial Catalog=tempdb; Integrated Security=true;User Instance=True;"))
        {
            connection.Open();

            using (var command = connection.CreateCommand())
            {

                try
                {

                    command.CommandText = "DROP DATABASE " + dbName;
                    command.ExecuteNonQuery();

                }
                catch {}

                command.CommandText = "CREATE DATABASE " + dbName + " ON PRIMARY (NAME=" + dbName + ", FILENAME='" + filename + "')";
                command.ExecuteNonQuery();

                command.CommandText = "EXEC sp_detach_db '" + dbName + "', 'true'";
                command.ExecuteNonQuery();
            }
        }
    }

    private DatabaseAdapter<T> CreateDataAdapter<T>(String primaryKey)
    {
        return new DatabaseAdapter<T>(typeof(T), CONNECTION_STRING, primaryKey, typeof(T).Name, DBSet.DataSetName);
    }

    private DataTable CreateDataTable<T>()
    {
        DataTable dt = new DataTable();

        PropertyInfo[] properties = typeof(T).GetProperties();

        if (properties.Length == 0) { throw new Exception("Type has no properties"); }

        for (int i = 0; i < properties.Length; i++)
        {
            try
            {
                dt.Columns.Add(new DataColumn(properties[i].Name, properties[i].PropertyType, null, MappingType.Attribute));
            }
            catch { throw new Exception("Cannot add columns"); }
        }

        return dt;
    }

    public DataTable GetTable<T>()
    {
        for (int i = 0; i < DBSet.Tables.Count; i++)
        {
            if (DBSet.Tables[i].TableName == typeof(T).Name)
            {
                return DBSet.Tables[i];
            }
        }

        throw new Exception("Table not found");
    }

    public static SqlDbType GetDBType(Type t)
    {

        if (t == typeof(bool))
        {
            return SqlDbType.Bit;
        }
        else if (t == typeof(String))
        {
            return SqlDbType.Text;
        }
        else if (t == typeof(Int16))
        {
            return SqlDbType.SmallInt;
        }
        else if (t == typeof(Int32))
        {
            return SqlDbType.Int;
        }
        else if (t == typeof(Int64))
        {
            return SqlDbType.BigInt;
        }
        else if (t == typeof(byte))
        {
            return SqlDbType.TinyInt;
        }
        else if (t == typeof(long))
        {
            return SqlDbType.Money;
        }
        else if (t == typeof(char))
        {
            return SqlDbType.Char;
        }
        else if (t == typeof(Image))
        {
            return SqlDbType.VarBinary;
        }
        else if (t == typeof(Byte[]))
        {
            return SqlDbType.VarBinary;
        }
        else if (t == typeof(sbyte[]))
        {
            return SqlDbType.VarBinary;
        }
        else if (t == typeof(DateTime))
        {
            return SqlDbType.DateTime;
        }
        else if (t == typeof(float) || t == typeof(double))
        {
            return SqlDbType.Float;
        }
        else if (t == typeof(Guid))
        {
            return SqlDbType.UniqueIdentifier;
        }
        else if (t == typeof(Decimal))
        {
            return SqlDbType.Decimal;
        }

        return SqlDbType.Text;
    }

}

my own Adapter class:

public class DatabaseAdapter<T> : global::System.ComponentModel.Component
{

    #region FIELDS

    private bool _clearBeforeFill = true;

    private global::System.Data.SqlServerCe.SqlCeDataAdapter _adapter;
    private global::System.Data.SqlServerCe.SqlCeConnection _connection;
    private global::System.Data.SqlServerCe.SqlCeTransaction _transaction;
    private global::System.Data.SqlServerCe.SqlCeCommand[] _commandCollection;

    private string ConnectionString;
    private string TableName;
    private string PrimaryKey;
    private string DataSetTable;
    private Type SourceType;

    private PropertyInfo[] classProperties;

    #endregion

    public DatabaseAdapter(Type sourceType, String connectionString, String primaryKey, String tableName, String dataSetTable)
    {

        ConnectionString = connectionString;
        TableName = tableName;
        DataSetTable = dataSetTable;
        SourceType = sourceType;
        PrimaryKey = primaryKey;
        classProperties = sourceType.GetProperties();

        Init();
    }

    public void Init()
    {
        #region INITIALIZE CONNECTION

        this._connection = new System.Data.SqlServerCe.SqlCeConnection();
        this._connection.ConnectionString = ConnectionString;

        #endregion

        #region INITIALIZE ADAPTER

        this._adapter = new System.Data.SqlServerCe.SqlCeDataAdapter();
        global::System.Data.Common.DataTableMapping tableMapping = new global::System.Data.Common.DataTableMapping();

        #endregion

        #region SET TABLE SOURCE

        tableMapping.SourceTable = TableName;
        tableMapping.DataSetTable = DataSetTable;

        #endregion

        #region SET PRIMARY KEY / GET PRIMARY KEY TYPE

        SqlDbType primaryType = SqlDbType.Text;

        for (int i = 0; i < classProperties.Length; i++)
        {
            try
            {
                tableMapping.ColumnMappings.Add(classProperties[i].Name, classProperties[i].Name);

                if (PrimaryKey == classProperties[i].Name)
                {
                    primaryType = DataAccess.GetDBType(classProperties[i].PropertyType);
                }
            }
            catch { }
        }

        this._adapter.TableMappings.Add(tableMapping);

        #endregion

        #region ADD DELETE COMMAND

        this._adapter.DeleteCommand = new System.Data.SqlServerCe.SqlCeCommand();
        this._adapter.DeleteCommand.Connection = this.Connection;
        this._adapter.DeleteCommand.CommandText = "DELETE FROM [" + TableName + "] WHERE (([" + PrimaryKey + "] = @p1))";
        this._adapter.DeleteCommand.Parameters.Add(new global::System.Data.SqlServerCe.SqlCeParameter("@p1", primaryType, 0, global::System.Data.ParameterDirection.Input, false, 0, 0, PrimaryKey, global::System.Data.DataRowVersion.Original, null));

        #endregion

        #region ADD INSERT / UPDATE COMMANDS

        String ifields = "";
        String ivalues = "";

        String ufields = "";

        int count = 1;

        this._adapter.InsertCommand = new System.Data.SqlServerCe.SqlCeCommand();
        this._adapter.InsertCommand.Connection = this.Connection;
        this._adapter.InsertCommand.CommandType = CommandType.Text;

        this._adapter.UpdateCommand = new System.Data.SqlServerCe.SqlCeCommand();
        this._adapter.UpdateCommand.Connection = this.Connection;
        this._adapter.UpdateCommand.CommandType = CommandType.Text;


        for (int i = 0; i < classProperties.Length; i++)
        {
            try
            {

                ifields += "[" + classProperties[i].Name + "], ";
                ivalues += "@p" + count + ", ";

                ufields += "[" + classProperties[i].Name + "] = @p" + count + ", ";

                this._adapter.InsertCommand.Parameters.Add(new global::System.Data.SqlServerCe.SqlCeParameter("@p" + count, DataAccess.GetDBType(classProperties[i].PropertyType), 0, global::System.Data.ParameterDirection.Input, true, 0, 0, classProperties[i].Name, global::System.Data.DataRowVersion.Current, null));

                count++;

            }
            catch { }
        }

        ifields = ifields.Substring(0, ifields.Length - 1);
        ivalues = ivalues.Substring(0, ivalues.Length - 1);

        ufields = ufields.Substring(0, ufields.Length - 1);

        this._adapter.InsertCommand.CommandText = "INSERT INTO [" + TableName + "] (" + ifields + ") VALUES (" + ivalues + ")";
        this._adapter.UpdateCommand.Parameters.Add(new global::System.Data.SqlServerCe.SqlCeParameter("@p" + count, primaryType, 0, global::System.Data.ParameterDirection.Input, true, 0, 0, PrimaryKey, global::System.Data.DataRowVersion.Original, null));
        this._adapter.UpdateCommand.CommandText = "UPDATE [" + TableName + "] SET " + ufields + " WHERE (([" + PrimaryKey + "] = @p" + count + "))";

        #endregion

        #region INITIALIZE COMMAND COLLECTION / SET SELECT COMMAND

        this._commandCollection = new global::System.Data.SqlServerCe.SqlCeCommand[1];
        this._commandCollection[0] = new global::System.Data.SqlServerCe.SqlCeCommand();
        this._commandCollection[0].Connection = this.Connection;
        this._commandCollection[0].CommandText = "SELECT " + ifields + " FROM [" + TableName + "]";
        this._commandCollection[0].CommandType = global::System.Data.CommandType.Text;

        #endregion

    }

    #region FILL / INSERT / UPDATE / DELETE

    public virtual int Fill(DataTable dataTable)
    {

        this.Adapter.SelectCommand = this.CommandCollection[0];

        if (this.ClearBeforeFill)
        {
            dataTable.Clear();
        }

        return this.Adapter.Fill(dataTable);
    }

    public virtual int Update(object[] parameters)
    {

        if (parameters.Length == this.Adapter.UpdateCommand.Parameters.Count)
        {

            if (parameters.Length == classProperties.Length)
            {
                if (CheckParameters(parameters))
                {
                    for (int i = 0; i < parameters.Length; i++)
                    {
                        this.Adapter.UpdateCommand.Parameters[i].Value = parameters[i];
                    }

                    global::System.Data.ConnectionState previousConnection = this.Adapter.UpdateCommand.Connection.State;

                    if (((this.Adapter.UpdateCommand.Connection.State & global::System.Data.ConnectionState.Open) != global::System.Data.ConnectionState.Open))
                    {
                        this.Adapter.UpdateCommand.Connection.Open();
                    }

                    try
                    {
                        int returnValue = this.Adapter.UpdateCommand.ExecuteNonQuery();

                        return returnValue;
                    }
                    finally
                    {
                        if (previousConnection == global::System.Data.ConnectionState.Closed)
                        {
                            this.Adapter.UpdateCommand.Connection.Close();
                        }
                    }
                }

            }

        }

        return 0;

    }

    public virtual int Insert(object[] parameters)
    {
        if (parameters.Length == this.Adapter.InsertCommand.Parameters.Count)
        {
            if (parameters.Length == classProperties.Length)
            {
                if (CheckParameters(parameters))
                {

                    for (int i = 0; i < parameters.Length; i++)
                    {
                        this.Adapter.InsertCommand.Parameters[i].Value = parameters[i];
                    }

                    global::System.Data.ConnectionState previousConnection = this.Adapter.InsertCommand.Connection.State;

                    if (((this.Adapter.InsertCommand.Connection.State & global::System.Data.ConnectionState.Open) != global::System.Data.ConnectionState.Open))
                    {
                        this.Adapter.InsertCommand.Connection.Open();
                    }

                    try
                    {
                        int returnValue = this.Adapter.InsertCommand.ExecuteNonQuery();

                        return returnValue;
                    }
                    finally
                    {

                        if (previousConnection == global::System.Data.ConnectionState.Closed)
                        {
                            this.Adapter.InsertCommand.Connection.Close();
                        }
                    }

                }
            }
        }

        return 0;
    }

    public virtual int Delete(object value)
    {

        bool valid = false;

        for (int i = 0; i < classProperties.Length; i++)
        {
            if (PrimaryKey == classProperties[i].Name)
            {
                if (classProperties[i].PropertyType == value.GetType())
                {
                    valid = true;
                }
            }
        }

        if (valid)
        {
            this.Adapter.DeleteCommand.Parameters[0].Value = value;
            global::System.Data.ConnectionState previousConnection = this.Adapter.InsertCommand.Connection.State;

            if (((this.Adapter.DeleteCommand.Connection.State & global::System.Data.ConnectionState.Open) != global::System.Data.ConnectionState.Open))
            {
                this.Adapter.DeleteCommand.Connection.Open();
            }

            try
            {
                int returnValue = this.Adapter.DeleteCommand.ExecuteNonQuery();
                return returnValue;
            }
            finally
            {
                if ((previousConnection == global::System.Data.ConnectionState.Closed))
                {
                    this.Adapter.DeleteCommand.Connection.Close();
                }
            }
        }

        return 0;
    }

    private bool CheckParameters(object[] parameters)
    {
        for (int i = 0; i < parameters.Length; i++)
        {
            if (parameters[i].GetType() != classProperties[i].PropertyType)
            {
                return false;
            }
        }

        return true;
    }

    #endregion

    #region MISC

    #endregion

    #region PROPERTIES

    protected internal global::System.Data.SqlServerCe.SqlCeDataAdapter Adapter
    {
        get
        {
            return this._adapter;
        }
    }

    internal global::System.Data.SqlServerCe.SqlCeConnection Connection
    {
        get
        {
            return this._connection;
        }
        set
        {
            this._connection = value;
            if ((this.Adapter.InsertCommand != null))
            {
                this.Adapter.InsertCommand.Connection = value;
            }
            if ((this.Adapter.DeleteCommand != null))
            {
                this.Adapter.DeleteCommand.Connection = value;
            }
            if ((this.Adapter.UpdateCommand != null))
            {
                this.Adapter.UpdateCommand.Connection = value;
            }
            for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1))
            {
                if ((this.CommandCollection[i] != null))
                {
                    ((global::System.Data.SqlServerCe.SqlCeCommand)(this.CommandCollection[i])).Connection = value;
                }
            }
        }
    }

    internal global::System.Data.SqlServerCe.SqlCeTransaction Transaction
    {
        get
        {
            return this._transaction;
        }
        set
        {
            this._transaction = value;

            for (int i = 0; (i < this.CommandCollection.Length); i = (i + 1))
            {
                this.CommandCollection[i].Transaction = this._transaction;
            }
            if (((this.Adapter != null)
                        && (this.Adapter.DeleteCommand != null)))
            {
                this.Adapter.DeleteCommand.Transaction = this._transaction;
            }
            if (((this.Adapter != null)
                        && (this.Adapter.InsertCommand != null)))
            {
                this.Adapter.InsertCommand.Transaction = this._transaction;
            }
            if (((this.Adapter != null)
                        && (this.Adapter.UpdateCommand != null)))
            {
                this.Adapter.UpdateCommand.Transaction = this._transaction;
            }
        }
    }

    protected global::System.Data.SqlServerCe.SqlCeCommand[] CommandCollection
    {
        get
        {
            return this._commandCollection;
        }
    }

    public bool ClearBeforeFill
    {
        get { return _clearBeforeFill; }
        set { _clearBeforeFill = value; }
    }

    public Type ObjectType
    {
        get { return SourceType; }
    }

    #endregion

}
share|improve this question
1  
I'm pretty new to this site, but I don't think this is the correct sort of question for this site. This site is more about 'I've written this code, how could I make it better', whereas stackoverflow.com is more about 'I have this problem, how do I fix it'. If you ask this question on there you will more likely get an answer extremely quickly. – dormisher May 8 '12 at 16:12
And at stackoverflow they say the code is too much and beyond the site's scope - that I should ask on this site... So, which one is it? – Deukalion May 9 '12 at 12:56
I would say that the people who told you that on stackoverflow are some of the ***'s who have recently been getting arsey to me as well about the content of questions over there. I think it is maybe getting difficult to define what each of the programming related stack exchange sites is actually for. Though another way to look at this is maybe your question is too broad - try slimming your question down to a specific problem / smaller section of code and you might get an answer on stackoverflow. – dormisher May 9 '12 at 13:23
There is no site on the se network which will debug your code for you. For stack overflow, you need to narrow your question as much as possible and give your problem a much better description. Its not really clear whats wrong from your current question. – Winston Ewert May 10 '12 at 14:01

closed as off topic by Winston Ewert May 10 '12 at 14:01

Questions on Code Review - Stack Exchange are expected to relate to code review request within the scope defined in the FAQ. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about closed questions here.

Browse other questions tagged or ask your own question.