На C# я пишу редко, и в основном все наши приложения и сервисы подключаются к источнику данных, используя MSSQL сервер или службы баз данных. И вот настало время написать приложение, используя не сервер, а локальную БД. Немного погуглив, я внезапно выбрал SQLite.
Предисловие
У всех наших заказчиков были требования к коду:
- установленное именование переменных;
- группировка кода (конструкторы, переменные, методы, события…);
- табы и форматирование (каралось смертной казнью);
- за самописные SQL запросы разработчик удалялся из команды.
Исходя из вышеперечисленного, для баз данных конечно же были использованы классы LINQ to SQL, связанные с реляционными объектами.
Естественно, в моем десктопном приложении я сразу же скачал и установил SQLite провайдер, создал базу данных, все таблички, связи, создал класс LINQ to SQL, перетянул в него все объекты с обозревателя, и…
![](https://habrastorage.org/files/ff0/4cc/edd/ff04ccedd43347b2a4aeb5aae3dd93f0.jpg)
Что делать? Куда бежать?
Конечно же в гугл, с которого плавно перебегаем в stackoverflow! Там у нас over9000 вариантов:
- да давайте все писать с начала (SQLiteConnection, SQLiteCommand, SQLiteDataReader, SQLiteDataRecord и т.д.):
- давайте писать запросы вручную;
- давайте при изменении или добавлении одного поля в таблицу перелопатим весь проект;
- связи между таблицами для слабаков, будем использовать DataTable и работать с ним по индексам столбцов…
Нет, нет, и еще раз нет. С данными должен работать класс, который отвечает за подключение к БД, выборку, вставку, обновление и удаление записей (DataContext), а разработчик должен использовать объекты, именованные так же, как и реляционные объекты и их свойства!
Решение
Больше ничего не осталось, как искать «левые» генераторы кода для таблицы. Немного погуглив и взвесив все «за» и «против», я остановился на dblinq2007.
Как оказалось позже, он может генерировать не просто файл с исходным кодом, а студийный LINQ to SQL файл со схемой нашей БД и связями! Это как раз то, что и нужно было, и я приступил к разработке. Первый exception: dblinq2007 написан и генерирует схему для Framework 2.0, а мы используем 4.0. Качаем исходники, открываем в студии, в свойствах проектов выбираем 4ю версию фреймворка и пересобираем dblinq2007!
Генерация кода
Для генерации необходимо использовать исполняемый файл dblinq2007, который лежит в директории скомпилированных бинарников и называется DbMetal.exe. Немного покурим его доки, и, просмотрев справку, мы видим, что достаточно указать провайдера, строку подключения и имя файла, и DbMetal сгенерирует нам DBML файл для SQLite:
Генерируем DBML-модель:
После генерации DBML нам необходимо сгенерировать CS файл (должен называться так же, как и DBML файл), в котором и будет описана структура нашей БД со всеми связями. Основной сгенерируемый класс Main унаследован от класса DataContext, в котором и реализована работа с SQLite.
Теперь, когда все файлы сгенерированы, копируем их в директорию нашего проекта и добавляем в проект DBML файл. Чтобы увидеть, что студия теперь работает с SQLite, достаточно в Обозревателе серверов выделить все таблички, и перетянуть их в DBML конструктор:
Победа!
В принципе, все. После проделанных манипуляций мы сможем писать LINQ запросы к нашей БД и нам будут возвращаться объекты со всеми связями.
public class Test { private void Example() { //берем из конфига строку подключения и подключаемся к БД SQLiteConnection Connection = new SQLiteConnection(Properties.Settings.Default.connectionString); Connection.Open(); //тот самый DatabaseContext, через который мы работаем с БД Main dbContext = new Main(Connection, new SqliteVendor()); //получаем данные List<Order> OrderList = (from o in dbContext.Order select o).ToList(); //или так List<Order> OrderList = dbContext.Order.Take(10).ToList(); //получаем статус заказа из связанной таблицы string OrderStatus = OrderList[0].OrderStatus.Name; //получаем все позиции заказа List<OrderUnit> OrderUnits = OrderList[0].OrderUnit.ToList(); //получаем изображения позиции List<MenuImages> UnitImages = OrderList[0].OrderUnit[0].Menu.MenuImages.ToList(); //вставляем данные Order ord = new Order() { OrderNumber = 1, ToTime = DateTime.Now }; dbContext.Order.InsertOnSubmit(ord); dbContext.SubmitChanges(); //Удаляем данные dbContext.Order.DeleteOnSubmit(OrderList[0]); dbContext.SubmitChanges(); //закрываем подключение Connection.Close(); } }
ссылка на оригинал статьи http://habrahabr.ru/post/262279/
Добавить комментарий