Re: Мой велосипед
От: HOMO_PROGRAMMATIS  
Дата: 01.03.10 21:19
Оценка:
В результате копания удалось таки найти пару примеров, из которых собралось остальное.
Вот мой код. Сразу скажу, что он рассматривает лишь те случаи, что мне нужны. Впрочем, кроме кода генерации таблицы остальное должно работать "почти всегда". Я выбрал бд SQLite как довольно популярную.

На вход принимает установленное соединение и собственно схему в виде DataSet

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SQLite;
using System.Diagnostics;

namespace SQLiteDesign
{
    class OpenTable
    {
        public SQLiteDataAdapter    Adapter;
        public DataTable            Table;
    }

    class SQLiteDatabase
    {
        protected SQLiteConnection    m_DbConnection;
        protected DataSet            m_Dataset;
        protected List<OpenTable>    m_OpenTables;

        public SQLiteDatabase(SQLiteConnection a_DbConnection, DataSet a_DataSet)
        {
            m_DbConnection = a_DbConnection;
            m_Dataset = a_DataSet;
        }

        public DataSet DataSet
        {
            get
            {
                return m_Dataset;
            }
        }
        
        protected virtual string NetTypeToSQLiteType(Type a_NetType)
        {
            switch (a_NetType.Name)
            {
                case "String":
                    return "text";
                case "UInt64":
                case "UInt32":
                case "UInt16":
                case "UInt8":
                case "Int64":
                case "Int32":
                case "Int16":
                case "Int8":
                    return "integer";
                case "double":
                    return "real";
            }

            string errorText = "Bad type in NetTypeToSQLiteType:" + a_NetType.Name;
            Debug.Assert(false, errorText);
            throw new global::System.ArgumentException(errorText);
        }
        
        // WARNING this method is not finished and ignores many features
        protected string GetCreateTableSql(DataTable a_Table)
        {
            StringBuilder resultBuilder = new StringBuilder();
            resultBuilder.Append("CREATE TABLE IF NOT EXISTS ");
            resultBuilder.Append(a_Table.TableName);
            resultBuilder.Append(" (");

            for (int i = 0; i < a_Table.Columns.Count; i++)
            {
                DataColumn currColumn = a_Table.Columns[i];
                if (i != 0)
                    resultBuilder.Append(", ");
                
                resultBuilder.Append(currColumn.ColumnName);
                resultBuilder.Append(" ");
                resultBuilder.Append(NetTypeToSQLiteType(currColumn.DataType));

                if (a_Table.PrimaryKey.Contains(currColumn))
                    resultBuilder.Append(" PRIMARY KEY");
            }

            resultBuilder.Append(");");
            
            return resultBuilder.ToString();
        }
        
        public void CreateTables()
        {
            foreach (DataTable currTable in m_Dataset.Tables)
            {
                SQLiteCommand createTableCmd = m_DbConnection.CreateCommand();
                createTableCmd.CommandText = GetCreateTableSql(currTable);
                createTableCmd.ExecuteNonQuery();
            }
        }
        
        public void OpenTables()
        {
            if (m_OpenTables != null)
                return;
                
            m_OpenTables = new List<OpenTable>();

            foreach (DataTable currTable in m_Dataset.Tables)
            {
                OpenTable newTable = new OpenTable();
                newTable.Table = currTable;
                newTable.Adapter = new SQLiteDataAdapter("Select * from " + currTable.TableName, m_DbConnection);
                newTable.Adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey;
                newTable.Adapter.Fill(m_Dataset, currTable.TableName);

                SQLiteCommandBuilder cmdBuilder = new SQLiteCommandBuilder(newTable.Adapter);

                m_OpenTables.Add(newTable);
            }
        }
        
        public void SaveChanges()
        {
            if (m_OpenTables == null)
                return;

            foreach (OpenTable currTable in m_OpenTables)
            {
                currTable.Adapter.Update(currTable.Table);
            }
        }
    }
}


Пример:

    TestDataSet myDataSet = new TestDataSet();

    SQLiteConnection dbConnection = new SQLiteConnection();
    dbConnection.ConnectionString = "Data Source=test.db";
    dbConnection.Open();

    SQLiteDatabase db = new SQLiteDatabase(dbConnection, myDataSet);
    db.CreateTables();
    db.OpenTables();

    TestDataSet.DataTable1Row myDataRow1 = myDataSet.DataTable1.NewDataTable1Row();
    myDataRow1.DataColumn1 = "Something1";
    myDataRow1.DataColumn2 = "Test1";
    myDataSet.DataTable1.Rows.Add(myDataRow1);

    TestDataSet.DataTable2Row myDataRow2 = myDataSet.DataTable2.NewDataTable2Row();
    myDataRow2.DataColumn1 = "Something2";
    myDataRow2.DataColumn2 = "Test2";
    myDataSet.DataTable2.Rows.Add(myDataRow2);

    db.SaveChanges();
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.