Создать БД из DataSet
От: HOMO_PROGRAMMATIS  
Дата: 28.02.10 16:34
Оценка:
Здравствуйте.
Третий день мучаюсь с гуглом, все без толку

Сдизайнил я DataSet в Data Sources. В нем несколько простых таблиц. Теперь я хочу совершенно естественную вещь — чтобы
1) Если базы данных на диске еще нет, она создавалась по этой схеме
2) Если есть — чтобы с ней можно было работать используя этот типизированный DataSet, не записывая никакого SQL вообще.

В случае с хранением в XML все работает на ура, а вот с базами данных никак не пойму. Все примеры в интернете что я смог найти либо напрочь не используют дизайнер, либо в самом лучшем случае работают лишь с одной таблицей за раз, да и то без SQL не обошлось.
Re: Создать БД из DataSet
От: Mihas  
Дата: 01.03.10 10:40
Оценка: 1 (1)
HOM>Сдизайнил я DataSet в Data Sources. В нем несколько простых таблиц. Теперь я хочу совершенно естественную вещь — чтобы
HOM>1) Если базы данных на диске еще нет, она создавалась по этой схеме
Выгрузи в файл XSD-схему своего датасета (DataSet.WriteXml — вроде так). В обратную сторону DataSet.ReadXml.
Если я правильно понял вопрос.

HOM>2) Если есть — чтобы с ней можно было работать используя этот типизированный DataSet, не записывая никакого SQL вообще.

Может быть, DataAdapter поможет? Хотя я ни разу им не пользовался, и как работает, не знаю.
Re: Создать БД из DataSet
От: _FRED_ Черногория
Дата: 01.03.10 11:01
Оценка: 1 (1)
Здравствуйте, HOMO_PROGRAMMATIS, Вы писали:

HOM>Третий день мучаюсь с гуглом, все без толку


HOM>Сдизайнил я DataSet в Data Sources. В нем несколько простых таблиц. Теперь я хочу совершенно естественную вещь — чтобы

HOM>1) Если базы данных на диске еще нет, она создавалась по этой схеме

С каких пор эта "вещь" является естественной

HOM>2) Если есть — чтобы с ней можно было работать используя этот типизированный DataSet, не записывая никакого SQL вообще.


HOM>В случае с хранением в XML все работает на ура, а вот с базами данных никак не пойму. Все примеры в интернете что я смог найти либо напрочь не используют дизайнер, либо в самом лучшем случае работают лишь с одной таблицей за раз, да и то без SQL не обошлось.


В каком виде нужна созданная база данных? SQL Server? MS Access? Oracle?

В DataSet нет способа хранения StoredProcedures — как создавать их? Или они не нужны?
В DataSet нет способа описания чеков (CHECK Constraint).
В DataSet нет много чего ещё, необходимого базе данных. Это причины, по которым "в коробке" нет способа создания базы данных из датасета.

Если есть возможность, посмотрите в сторону Entity Framework — кажется, там есть возможность создания БД по метаданным. Думаю, только для SQL Server.
Help will always be given at Hogwarts to those who ask for it.
Re: Создать БД из DataSet
От: Pavel Dvorkin Россия  
Дата: 01.03.10 12:24
Оценка: 2 (1)
Здравствуйте, HOMO_PROGRAMMATIS, Вы писали:

HOM>Здравствуйте.

HOM>Третий день мучаюсь с гуглом, все без толку

HOM>Сдизайнил я DataSet в Data Sources. В нем несколько простых таблиц. Теперь я хочу совершенно естественную вещь — чтобы

HOM>1) Если базы данных на диске еще нет, она создавалась по этой схеме
HOM>2) Если есть — чтобы с ней можно было работать используя этот типизированный DataSet, не записывая никакого SQL вообще.

HOM>В случае с хранением в XML все работает на ура, а вот с базами данных никак не пойму. Все примеры в интернете что я смог найти либо напрочь не используют дизайнер, либо в самом лучшем случае работают лишь с одной таблицей за раз, да и то без SQL не обошлось.


Как утверждают тут

http://davidhayden.com/blog/dave/archive/2006/01/27/2775.aspx

SQL Server Management Objects are a cool new feature with SQL Server 2005 that allow you to create database objects ( tables, stored procedures, etc.) programmatically using C# and VB.NET.

Дальше копай сам, если интересно.
With best regards
Pavel Dvorkin
Re[2]: Создать БД из DataSet
От: HOMO_PROGRAMMATIS  
Дата: 01.03.10 21:12
Оценка:
_FR>С каких пор эта "вещь" является естественной
Ну для меня — совершенно. Не все же читают готовые бд, я видел дополна приложений что создают бд на лету. Логично, что удобно создавать их по изготовленной схеме а не копипастить все второй раз в другом виде

_FR>В каком виде нужна созданная база данных? SQL Server? MS Access? Oracle?

Раз ADO.NET это слой абстракции, то и я бы хотел абстрактно, чтобы сам движок бд заменялся.

_FR>В DataSet нет...

Как я сказал, таблицы простые.

_FR>Если есть возможность, посмотрите в сторону Entity Framework — кажется, там есть возможность создания БД по метаданным. Думаю, только для SQL Server.

Я забыл сказать, предполагается встраиваемая бд.
Re[2]: Создать БД из DataSet
От: HOMO_PROGRAMMATIS  
Дата: 01.03.10 21:14
Оценка:
Здравствуйте, Mihas, Вы писали:

M>Выгрузи в файл XSD-схему своего датасета (DataSet.WriteXml — вроде так). В обратную сторону DataSet.ReadXml.

M>Если я правильно понял вопрос.
Похоже неправильно

M>Может быть, DataAdapter поможет? Хотя я ни разу им не пользовался, и как работает, не знаю.

Да, оказывается поможет.
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();
Re[2]: Хотя тут есть проблема
От: HOMO_PROGRAMMATIS  
Дата: 02.03.10 08:47
Оценка:
А именно, DataSet хранит все данные в памяти, получается что вся бд туда загружается. Надо что-то с этим сделать будет, видимо уточнить запросы для селектов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.