Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Общие вопросы по .NET и C# > Работа с базами в .Net |
Автор: Nastya 10.9.2004, 20:28 |
Люди, товарищи, человеки! Какие ест подходы к базам в .Net. Через какие классы, службы и т.д. Есдит можно ссылочку на хорошую доку с примерами. Если можно ориентированно на visulStudio .Net и C# |
Автор: mr.DUDA 10.9.2004, 22:00 |
А что за тип БД ? Для SQL Server в .NET есть набор классов начиная с SqlConnection, для "просто ADO" есть OleDbConnection и т.п. А вообще, имхо, лучше всего начать с общих принципов работы с датасетами, таблицами и т.п. - например просмотреть классы DataSet, DataTable, DataRow. Методы работы с ними ОЧЕНЬ похожи на работу с обычными массивами, так что усвоить будет легко. А конкретизированные классы для работы с ADO/SQLServer и т.п. в конце концов сводятся к датасету, так что вот... ![]() |
Автор: Kurt 11.9.2004, 02:58 | ||||||||||||||||||||
Для работы с базами данных в .NET разработана новая технология ADO.NET. Хочется отметить, что, несмотря на вызывающее асоциации название, она не является расширением классического ADO. Это ИНАЯ модель. Не буду говорить лучше или хуже, здесь судит каждый сам, пусть будет "иная". ![]() ADO.NET ориентирована на построение рассоединенных (diconnected) систем на .NET-платформе. Суть рассоединенных систем заключается в следующем: исходя из того, что часто требуется минимизировать нагрузку на сеть, на стороне пользователя создается какбы локальная копия базы данных, что хранится на сервере. Клиент изменяет этот локальных набор данных и лишь после коммита он отправляется на сервер (естественно, отправляется не все, а лишь изменения). Уже здесь видно отличие - классическая ADO рассчитана на клиент-серверные приложения, т.е. когда клиент и сервер постоянно взаимодействуют друг с другом, тем самым нагружая сеть. Конечно, ADO.NET тоже далеко не идеальна - например, набор данных, с которыми работает пользователь, может устареть (кто-нибудь другой изменил данные), однако, это все решается. ![]() Еще одно интересное решение в ADO.NET это то, что здесь реализована поддержка представления данных в XML-форматах. Что дает возможность переправлять данные через родной и всеми любимый HTTP - следовательно, отпадают проблемы с фаерволами. Итак, какие задачи решают типы ADO.NET? 1) Установить соединение; 2) Создать локальную копию данных; (для этого применяется класа DataSet) 3) Отключиться от сервера; 4) Вернуть изменения на сервер. Т.о. в центре внимания находится класс DataSet - локальный набор таблиц и информации об отношениях между ними. Это некий RecordSet из классического ADO, различия в том, что RecordSet хранит только одну таблицу, а DataSet - фактически полную копию всей базы. Как только создан и заполнен объект класса DataSet, к нему допустимы все операции, что и с обычными базами - добавлять/удалять записи, ставить фильтры и т.п. Когда все изменения будут закончены, информация будет отправлена на сервер. DataSet создается при помощи т.н. управляемого провайдера (managed provider) - набора классов, реализующих интерфейсы доступа к базе. В состав .NET-Framework 1.1 входят два провайдера: OleDb-провайдер (для хранилищ данных, к-е поддерживают формат OleDb) и SQL-провайдер (спец. адаптирован для работы с MSSQL Server 7.0 и выше). Т.е. ситуация такая: по возможности используется специализированный провайдер, позволяющий наиболее эффективно работать с конкретной СУБД. Если такого провайдера нет - используют OleDb. Т.к. в OleDb выполняется куча преобразований в формат OleDb, то этот способ медленнее, чем спец. провайдеры. На даный момент большинство фирм производителей СУБД стараются выпустить адаптированный провайдер. Так, выпустили или во всяком случае собираются выпустить провайдеры под MySQL (точно знаю, что выпущен..), Oracle, Cache, Postgres etc. Все типы ADO.NET содержатся в namespace System.Data, расположенном в сборке System.Data.dll. Любой ADO.NET-проект должен содержать ссылку на эту сборку. Кроме того, нужен будет тот или иной провайдер. "Стандартные" провайдеры содержатся в namespace'ах System.Data.SQL и System.Data.OleDb соответственно для SQL- и OleDb-провайдера. Если используется сборка третьей фирмы - нужно тоже ее подключить (как в случае с MySQL). Пространство имен System.Data содержит много типов, обеспечивающих работу с БД, но самыми основными являются: 1) DataSet; (локальная копия данных. Состоит из множества объектов DataTable, а также информацию об отношениями между ними) 2) DataTable; (представляет собой одну конкретную таблицу) 3) DataColumn; (столбец в объекте DataTable) 4) DataRow; (строка в объекте DataTable); DataColumn(с него проще начать) Как уже упоминалось, это отдельный столбец в таблице. Он содержит поля, определяющие характеристики данного столбца в таблице. Например, Caption (заголовок столбца), DataType (тип), AutoIncrement (для настройки автоинкремента) и д.р. Создадим столбец и добавим его в таблицу:
Или вот настроим автоинкремент:
DataRow Это одна конкретная строка таблицы. Класс содержит много интересных свойств и методов. Описывать их здесь нет особого смысла - существует куча документации на эту тему. Мне особенно понравился метод Delete() - ПОМЕТИТЬ строку как удаленную. Я специально выделил это слово - т.е. физически строка не будет удалена, пока не будет подана команда AcceptChanges() (метод этого же класса). Т.е. можно отменить удаление в любой момент (метод RejectChanges) Небольшой пример работы с этим классом:
DataTable Описывает таблицу из набора данных DataSet. Собственно, я уже использовал этот тип в примерах раньше. Повторяться не хочу, поэтому давайте сразу с примера, естественно, комментируя некоторые моменты.
Хорошо бы еще описать класс DataSet (например, как читать/сохранять данные из DataSet в XML-файлы, как реализовывать отношения между таблицами), но это уже явно перебор для одного раза. ![]() Упомяну лишь один, на мой взгляд, самый нужный метод - Add() - он добавляет таблицу в конкретный DataSet. Приблизительно, так:
С помощью вышесказанного уже можно построить вполне состоятельное приложение, к-е поддерживает все функции, кроме непосредственно сохранения в базе (ну, можно таблицы в XML-файлах посохранять). Т.е. выгрузим приложение - выгрузятся и наши данные. Вот тут-то на сцену и выходят управляемые провайдеры! Дальнейшее описание будет строиться на основе OleDb (все-таки, больше универсальности), а также на "СУБД" Access, да простят меня читающие эти строки. ![]() Сразу подключим наши namespace'ы:
Перечислим основные типы OleDb: 1) OleDbConnection; (Соединение с источником данных) 2) OleDbCommand; (Запрос к источнику данных) 3) OleDbDataAdapter; (о нем будт особо сказано ниже) 4) OleDbDataReader; (считывает данные из источника в одном направлении (только вперед)) 5) OleDbErrorCollection; (набор ошибок и предупреждений, к-е возвращает источник данных) 6) OleDbParameter; (параметр для передачи хранимой процедуре) Итак, чтобы подключиться к источнику данных используем объект класса OleDbConnection. Особенно важное св-во этого класса - ConnectionString: строка, характеризующая подключение к серверу. Например, подключимся к Access:
Естественно, для каждой СУБД свой ConnectionString. Теперь как выполнить запрос к источнику данных. Для этого, как уже было сказано, используется класс OleDbCommand. В конструкторе необходимо указать строку, содержащую SQL-запрос, а также созданное нами соединение. Чтение происходит с помощью OleDbDataReader:
Теперь уже можно написать простенького клиента к базе данных. Мы можем читать данные (правда, в одном направлении) и посылать управляющие запросы. Однако, причем здесь DataSet и все прочее? Как все-таки заполнить этот несчастный класс данными с сервера? Насколько я знаю, существует несколько способов, но самый простой и распространенный - использовать класс OleDbDataAdapter. Основная задача этого класса - автоматизация процессов редактирования, добавления и т.д. данных, однако, здесь я его расписывать не буду, упомяну лишь как заполнить DataSet. Для этого нужно создать объект класса OleDbDataAdapter на основе открытого соединения с сервером БД. Далее вызывается метод Fill, к-й автоматически и заполняет наш DataSet. Для отправления изменений используется метод Update(). Проиллюстрируем все это на примере:
........................ Думаю, пора заканчивать сей монумент. Это лишь самое начало. Здесь не затронуты вопросы хранимых процедур, работы с XML и т.д. Но это лучше в другой раз. Хочу заметить, что если вы замените "OleDb" в названиях классов на "Sql" или "ODBC", то получите соответсвенно классы для работы с MS SQL Server и ODBC. Надеюсь, это в какой-то степени является ликбезом в области ADO.NET и поможет вам в разработке .NET-приложений. Сейчас 4-е часа ночи, поэтому допускаю, что тут сделано куча ошибок и описок, кроме того, здесь рассказано как Я представляю себе ADO.NET, поэтому буду рад любым поправкам (можно через PM). ![]() Если есть необходимость продолжить - пишите, что следует раскрыть подробнее. З.Ы. Для того, чтобы отобразить таблицу в DataGrid достаточно использовать один метод:
|
Автор: December 11.9.2004, 10:11 |
Хотелось бы добавить, что скоро выйдет ADO.NET 2, в которой будет кое-что новое, а в частности - асинхронное выполнение запросов (например, BeginExecuteNonQuery, EndExecuteNonQuery). Реализовано три спосооба получения данных от асинхронного запроса, что довольно удобно. Подробнее об этом имеет смысл прочитать у мелкомягких (ссылку не помню). |
Автор: mr.DUDA 11.9.2004, 12:20 |
Если по-английски сойдёт, то вот "Practical Guide to .NET DataTables, DataSets and DataGrids": http://www.codeproject.com/csharp/PracticalGuideDataGrids1.asp http://www.codeproject.com/csharp/PracticalGuideDataGrids2.asp http://www.codeproject.com/csharp/PracticalGuideDataGrids3.asp Очень полная и неплохо построенная дока. |
Автор: stron 11.9.2004, 12:22 |
На форуме всё больше становится людей, интересующихся .NET-ом. IMHO, пора создавать ФАК 2 Kurt отличный материал |
Автор: Nastya 20.9.2004, 19:06 | ||
Как??? |
Автор: AntonSaburov 21.9.2004, 19:58 |
Да вообщем-то старыми дедовским способам - перегрузкой ![]() |
Автор: Nastya 26.9.2004, 09:55 |
Кстати оказывается, что для подключения к базам можно использовать не только ADO.NET, но и ODBC и других провайдеров. Что наиболее красива реализовано, так это то, что потом можно при помощи специальных классав типа OleDbDataAdapter, ODBCDataAdapter и т.д. Это все "приводить" к DataSet и работать обсолютно одинаково не взирая, так сказать на лица. Супер! Я была в вовсторге. Или я ошибаюсь? |
Автор: mr.DUDA 26.9.2004, 10:20 | ||
ADO.NET - это и есть та самая надстройка над разнотипными источниками данных (таких как ODBC, OLE DB, XML), позволяющая работать с ними через DataSet. |
Автор: Guest 9.11.2004, 12:15 |
Здравствуйте Kurt. Прошу прощенья за вопрос не по теме. Спасибо за ответ, эту статью я прочитал, но вопрос задал, случайно, не в ту тему. Код OleDbConnection conn = new OleDbConnection(); conn.ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;"+@"data source=G:\baza.mdb"; conn.Open(); string sSQL = "select * from superTable"; //этот запрос будет использоваться при выборке данных с сервера OleDbDataAdapter myAdapter = new OleDbDataAdapter(sSQL, conn); //создаем и заполняем DataSet DataSet myDS = new DataSet("MyDataSet"); try{ myAdapter.Fill(myDS, "superTable"); } catch(Exception ex){ //обрабатываем ошибку Console.WriteLine("Error! "+ex.Message); } finally //так или иначе, но мы должны закрыть соединение { conn.Close(); } .. //закончив изменения с DataSet, отправим изменения на сервер: myAdapter.Update(myDS, "superTable"); и для подключения в гриде: dataGrid1.SetDataBinding(myDS,"superTable"); //показываем таблицу с именем superTable Я не увидел явной связи между MyAdapter и myDS. Если можно, подскажите пожалуйста, - где можно прочитать об этом поподробнее (если можно на русском языке). И если не сильно затруднит какой ни будь примерчик: с mdb - файлом, скажем две связанные таблички и гридами кликнув на какой то записи чтоб открывался диалог с другим гридом и связанными записями (из первой табличке). ![]() Заранее благодарен. Garry |
Автор: Kurt 10.11.2004, 21:27 | ||||||
Ну, связь, вроде простая - DataAdapter позволяет автоматизировать работу с DataSet'ом. Вот смотрите:
Т.е. я заполняю DataSet всего одной строчкой. Виноват, двумя строчками, если считать SQL-запрос. Если делать без DataAdapter, то нужно вручную создавать таблицу в DataSet (DataTable someTable = new DataTable(..)..), исполнять запрос к базе, с помощью DataReader читать, создавать строки в DataTable.. А так - все просто. ![]()
Уточните, пожалуйста. Вы хотите все это сделать используя "локальную копию БД"? Т.е. манипулируя уже загруженными DataSet'ами? имхо, проще выполнить соотв. запрос в базу (select то-то и то-то from таблица1, таблица2 where..). Иногда проще выполнить коротенький запрос, чем занимать кучу оперативной памяти, забивая ее данными из таблицы.. Добавлено @ 21:29 P.S. Не хотите зарегистрироваться? Присоединяйтесь к нам на огонек - мы всегда рады новым людям. ![]() |
Автор: GarryKI 15.11.2004, 09:42 |
Всем добрый день! Kurt - спасибо за отзыв я зарегистрировался сразу после вопроса (Guest в вопросе теперь GarryKI). Конечно с запросом (SQL) удобнее. С базами и grid-ом у меня все примеры компилировались с ошибками, поэтому я задал этот вопрос. Затем с очередным примером получилось вставить данные запроса в грид при помощи DataAdapter. Но пример: 1. мне нужен что б понять структуру программы, например VS не всегда подхватывает второй файл *.cs и не какие namespace - не помогают, потом в очередной раз закроешь студию, - откроешь и все заработает, - это глюк или я что то не так делаю? 2. VS затирает в блоке инициализации все изменения, если вставлять изменения за комментариями TODO - не всегда все гладко срабатывает (компиляция). 3. Я правильно понимаю - Что для инициализации необходимо использовать метод "frm_load". Или как правильнее? 4. не хотелось бы создавать много OleDbConnection - ов к одной и тойже базе если мне нужны разные таблици из разных форм (одной программы (процесса))? Если это возможно подскажите пожалуйста как, если можно с примером (mdb - достаточно, мне главное понять). Заранее спасибо мой e-mail: [email protected] или ICQ: 172893304 |
Автор: Tomcat 15.11.2004, 11:00 |
Я, конечно, не Kurt, но... 1. Здесь не знаю... С такой бедой не сталкивался. Попробуй, может, просто сохранять проект перед компиляцией. 2. Уточни, пожалуйста. Где именно вставляешь, что выдает при ошибке. 3. Нет, такой необходимости нет. Хотя есть зависимость от того, что ты инициализируешь. Я обычно пользуюсь таким способом: все свои инициализации выделяю в отдельный метод формы, MyInit, какой-нибудь, и добавляю его вызов в конструктор. 4. Если работаешь с DataSet, то придется. DataAdapter используется обычно для связи одной таблицы DataSet и одной таблицы самой базы (хотя можно и такой запрос для DataAdapter написать, что связь будет иной, но это уже другие вопросы). Вот и получается, одна таблица - один адаптер. А по поводу примера, посмотри эти статьи... Помоему, здесь все не плохо расписано. http://www.aspnetmania.com/Articles/Category/4.html Только читай их от последней к первой. ![]() |
Автор: Srg 1.2.2005, 11:16 | ||||
Прошу прощения, но я не понял ответ на п.4
У себя я создаю один коннект к БД и раздаю его "всем, кто попросит". Например:
и таким образом в различных местах. |
Автор: seric 27.2.2006, 14:46 | ||
Пожалуйста подскажите!! Почему скорость работы при подключении к БД Access используя NET Framework 1.1 во много раз выше чем в NET Framework 2.0. Може чего не так делаю? Вот пример кода:
|
Автор: Exception 27.2.2006, 15:30 |
Давайте не оффтопить. Одна тема -- один вопрос. Это вам не свалка. Насчет перспектив развития ADO .NET скажу, что разрабатывается технология DLinq, которая произвела на меня огромное впечатление. Готовлю статью о технологии LINQ, и DLinq, в частности. |
Автор: Medved 27.2.2006, 21:01 |
По сабжу: http://msdn.microsoft.com/library/en-us/dnbda/html/daag.asp?frame=true в качестве дополнительного чтения (лишним не будет): http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/BOAGag.asp |
Автор: arilou 28.2.2006, 20:40 |
[offtop]Какую тему старую подняли, а зачем? ....... И где сейчас Kurt ? [/offtop] |
Автор: Xonxt 15.3.2008, 01:46 | ||||||
Товарищи. Простите, что поднимаю тему, но мне нужен ответ на "тривиальный" вопрос. Скажите в чем разница между этими двумя фрагментами:
с последующим вызовом этого метода:
и простым брутальным
??? Потому что, судя по всему, для компилятора разница огромная. Т.е. при выполнении первого фрагмента, оно ругается (я сделал обработку исключения с выводом текста ошибки в МесаджБокс) на "отсуствие значения одного или нескольких необходимых параметров", аа если я тупо задаю "1,1,1,1", как во втором фрагменте, то оно успешно добавляется. |
Автор: Xonxt 15.3.2008, 02:03 | ||
Черт. Разобрался. Нужно было просто брать в кавычки.
![]() ![]() ![]() Спасибо всем ![]() |
Автор: Xonxt 20.4.2008, 19:50 | ||||||||
Столкнулся с еще одной проблемой. Может ли кто-нибудь привести небольшой пример, как с помощью OleDB создать в базе данных новую таблицу? Допустим, есть:
Есть также
И есть
Как эту таблицу добавить в базу? Заранее благодарю ![]() Потому что в книге, по которой я этой разбираю (Джесс Либерти) есть только про добавление/удаление/изменение записей в конкретной таблице и с этим я уже разобрался - всё отлично работает. А вот про создание таблиц в книге ни слова :( ______ Попробовал по-другому:
Так оно ругается на имя поля "Key". При другом имени всё нормально. Подразумевается, что поле "Key" - это собственно ключевое поле с автоинкрементом. Помогите правильно построить SQL-запрос, чтобы получить таблицу с полями "Key, Name, Author, Year". |
Автор: thomas 20.4.2008, 20:11 | ||||||
Xonxt, Приветствую. Ну, во первых, для таких вопросов есть соответствующий раздел. "Базы данных под .NET" И вопросы относящиеся к базам данных в .NET надо задавать там. Во вторых, учим DDL, в котором как раз и существуют нужные тебе команды. А именно создание и удаление таблиц.
Надеюсь, ты знаешь как выполнить sql-команду. Успехов. ![]() Добавлено @ 20:21
Правильно ругаеться: KEY - зарезервированное слово.
|