Здравствуйте.
Третий день мучаюсь с гуглом, все без толку
Сдизайнил я DataSet в Data Sources. В нем несколько простых таблиц. Теперь я хочу совершенно естественную вещь — чтобы
1) Если базы данных на диске еще нет, она создавалась по этой схеме
2) Если есть — чтобы с ней можно было работать используя этот типизированный DataSet, не записывая никакого SQL вообще.
В случае с хранением в XML все работает на ура, а вот с базами данных никак не пойму. Все примеры в интернете что я смог найти либо напрочь не используют дизайнер, либо в самом лучшем случае работают лишь с одной таблицей за раз, да и то без SQL не обошлось.
HOM>Сдизайнил я DataSet в Data Sources. В нем несколько простых таблиц. Теперь я хочу совершенно естественную вещь — чтобы HOM>1) Если базы данных на диске еще нет, она создавалась по этой схеме
Выгрузи в файл XSD-схему своего датасета (DataSet.WriteXml — вроде так). В обратную сторону DataSet.ReadXml.
Если я правильно понял вопрос.
HOM>2) Если есть — чтобы с ней можно было работать используя этот типизированный DataSet, не записывая никакого SQL вообще.
Может быть, DataAdapter поможет? Хотя я ни разу им не пользовался, и как работает, не знаю.
Здравствуйте, 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.
Здравствуйте, HOMO_PROGRAMMATIS, Вы писали:
HOM>Здравствуйте. HOM>Третий день мучаюсь с гуглом, все без толку
HOM>Сдизайнил я DataSet в Data Sources. В нем несколько простых таблиц. Теперь я хочу совершенно естественную вещь — чтобы HOM>1) Если базы данных на диске еще нет, она создавалась по этой схеме HOM>2) Если есть — чтобы с ней можно было работать используя этот типизированный DataSet, не записывая никакого SQL вообще.
HOM>В случае с хранением в XML все работает на ура, а вот с базами данных никак не пойму. Все примеры в интернете что я смог найти либо напрочь не используют дизайнер, либо в самом лучшем случае работают лишь с одной таблицей за раз, да и то без SQL не обошлось.
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.
_FR>С каких пор эта "вещь" является естественной
Ну для меня — совершенно. Не все же читают готовые бд, я видел дополна приложений что создают бд на лету. Логично, что удобно создавать их по изготовленной схеме а не копипастить все второй раз в другом виде
_FR>В каком виде нужна созданная база данных? SQL Server? MS Access? Oracle?
Раз ADO.NET это слой абстракции, то и я бы хотел абстрактно, чтобы сам движок бд заменялся.
_FR>В DataSet нет...
Как я сказал, таблицы простые.
_FR>Если есть возможность, посмотрите в сторону Entity Framework — кажется, там есть возможность создания БД по метаданным. Думаю, только для SQL Server.
Я забыл сказать, предполагается встраиваемая бд.
Здравствуйте, Mihas, Вы писали:
M>Выгрузи в файл XSD-схему своего датасета (DataSet.WriteXml — вроде так). В обратную сторону DataSet.ReadXml. M>Если я правильно понял вопрос.
Похоже неправильно
M>Может быть, DataAdapter поможет? Хотя я ни разу им не пользовался, и как работает, не знаю.
Да, оказывается поможет.
В результате копания удалось таки найти пару примеров, из которых собралось остальное.
Вот мой код. Сразу скажу, что он рассматривает лишь те случаи, что мне нужны. Впрочем, кроме кода генерации таблицы остальное должно работать "почти всегда". Я выбрал бд 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 featuresprotected 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);
}
}
}
}
А именно, DataSet хранит все данные в памяти, получается что вся бд туда загружается. Надо что-то с этим сделать будет, видимо уточнить запросы для селектов.