Форум программистов, компьютерный форум, киберфорум
C#: Базы данных, ADO.NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/55: Рейтинг темы: голосов - 55, средняя оценка - 4.82
Модератор
Эксперт .NET
15468 / 10713 / 2787
Регистрация: 21.04.2018
Сообщений: 31,536
Записей в блоге: 2
1
SQLite

Code First - выбор: Microsoft.EntityFrameworkCore.Sqlite, Microsoft.Data.Sqlite, System.Data.SQLite и др.

22.09.2021, 19:48. Показов 10266. Ответов 96
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Работаю с БД очень редко.
Поэтому опыт маленький и знания обрывочные.

Стоит задача в Решении Framework 4.8 создать репозиторий на SQLite для такого контекста (пример):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
    [Table("Contacts")]
    public class ContactEntity
    {
        [Key]
        public int Id { get; set; }
 
        [Required]
        [Index]
        public string Name { get; set; }
    }
 
 
    [Table("Phones")]
    public class PhoneEntity
    {
        [Key]
        public int Id { get; set; }
 
        [Required]
        [Index]
        public int ContactId { get; set; }
 
        [Required]
        public string Title { get; set; }
 
        [Required]
        [Index]
        public string Number { get; set; }
    }
C#
1
2
3
4
5
6
7
8
9
10
11
    public class ContactDB : DbContext
    {
        public ContactDB(????)
            : base(????)
        {
 
        }
        public DbSet<ContactEntity> Contacts { get; set; }
        public DbSet<PhoneEntity> Phones{ get; set; }
 
    }
Как работать с существующей БД я более-менее понимаю.

Хотелка: реализация Code-First, то есть после запуска приложения в новом расположении без БД, что бы автоматически она была создана.

Доп. хотелки:
1) Запись в новую базу каких-то начальных данных (для образца);
2) Сделать независимые контексты для каждой сущности. То есть они могут быть в разных БД или в одной, но в разных таблицах. Это определяется уже при использовании репозитория передачей разных (каких?) параметров в конструктор.

Не знаю:
1) Для SQLite есть несколько разных основных пакетов, а к ним ещё и дополнительные. Какие лучше использовать?
2) Что ещё нужно добавить в конструктор и переопределяемые методы для реализации этой задачи? И насколько я понимаю, в зависимости от используемого комплекта пакетов, код реализации контекста может быть разный?
3) Атрибута [Index] для SQLite я не нашёл. Я его не там искал или его у SQLite DBContext нет? Если нет то как решить проблему быстроного поиска по нужному значению?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.09.2021, 19:48
Ответы с готовыми решениями:

System.data.sqlite не существует!
Всем добра. Я в качестве базы данных выбрал sqlite. скачал с офф сайта sqlite studio и sqlite...

Почему нет SQLite в разделе System.DATA
Не могу понять как сделать. чтобы подключение к SQLite было в System.Data. Подскажите пожалуйста. А...

Как включить поддержку ICU в System.Data.SQLite ?
Это повтор моей темы из рассылки sqlite http://sqlite.1065341.n5.nabble.com/ Как включить...

Не удалось найти запрошенного поставщика данных (System.Data.SQLite)
Добавил в код System.Data.SQLite.dll, подключил в начале кода, вместе с Common. Код простой,...

Установка System.Data.SQLite для Visual Studio 2015
Пытаюсь разобраться, как подключить SQLite к EF. Но первая же проблема - не могу скачать файл...

96
HF
1163 / 749 / 181
Регистрация: 09.09.2011
Сообщений: 2,314
Записей в блоге: 2
22.09.2021, 23:40 2
Если DbContext нужен - то разумеется только EF.
Если нужен лёгкий сервис без извращений - оригинальный System.Data.SQLite. Будет только 1 либа (+1 в нагрузку).
Microsoft.Data.Sqlite - это середнячок от микрософта, но он по сути - аналог оригинальной.

Соответственно - нужен контекст и всякие навороты с миграциями - только EF. Если готовы репозиторий и "миграции" сами создать - оригинал.

Я использую чистый.
"Репозиторий" сделал сам, или можно использовать SQLite.Net пакет, он чуть больше умеет.
Создание таблиц и миграции тоже сам написал в реализации - набор файлов скриптов и автовыполнение их при необходимости. Удобно - эти же файлы можно руками запускать.
1
Модератор
Эксперт .NET
15468 / 10713 / 2787
Регистрация: 21.04.2018
Сообщений: 31,536
Записей в блоге: 2
23.09.2021, 00:23  [ТС] 3
HF, спасибо.
Мне нужно с наименьшими рука-движениями.
Как уже писал - БД знаю плохо.
И как-то пока не возникло необходимости в изучении.
Поэтому, оптимально нужно что-то задать (код) в контексте и забыть об этом.
Дальше чтобы использовать как просто последовательности сущностей.


Цитата Сообщение от HF Посмотреть сообщение
Если DbContext нужен - то разумеется только EF.
Для System.Data.SQLite подтягивается System.Data.SqlClient.EF6 и контекст EF тоже можно использовать.
Но вот Code First (насколько разобрался) в нём нет.
Нужно ещё какой-то дополнительный пакет ставить.

Добавлено через 7 минут
HF, да, и забыл написать в вопросе (сейчас дополнил) о проблеме (для меня) атрибута [Index] для SQLite.
0
Эксперт .NET
12083 / 8391 / 1283
Регистрация: 21.01.2016
Сообщений: 31,636
23.09.2021, 00:53 4
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Microsoft.EntityFrameworkCore.Sqlite
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Framework 4.8
Эта связка не будет работать последние две или три версии EF Core работают только на .NET Core.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
после запуска приложения в новом расположении без БД, что бы автоматически она была создана.
EF Core так умеет. В конструкторе контекста вызываете метод EnsureCreated(). EF 6 так НЕ умеет.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Сделать независимые контексты для каждой сущности. То есть они могут быть в разных БД или в одной, но в разных таблицах.
Вот это я вообще не понял о чём вы.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но вот Code First (насколько разобрался) в нём нет.
Code First есть. Механизмов миграций для SQLite там нет.

Насчёт создания базы, если её нет. Вам для этого EF вообще не обязателен. Вы можете:
а) Или файл пустой базы (включая начальные данные) тащить с приложением. Когда надо создать базу, то просто сей файл копируете куда надо.
б) Создать эту базу руками и оставить её в проекте (но не в дистрибутиве конечного приложения). Потом просто экспортировать из неё SQL-скрипт (дамп) создания базы и наполнения данными. Этот скрипт всегда можно выполнить для создания новой базы.

Я бы выбирал из этих двух вариантов, а не налегал бы на возможности миграции EF'а.
0
Модератор
Эксперт .NET
15468 / 10713 / 2787
Регистрация: 21.04.2018
Сообщений: 31,536
Записей в блоге: 2
23.09.2021, 10:06  [ТС] 5
Цитата Сообщение от Usaga Посмотреть сообщение
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Сделать независимые контексты для каждой сущности. То есть они могут быть в разных БД или в одной, но в разных таблицах.
Вот это я вообще не понял о чём вы.
Мы с вами как-то общались на близкую тему.
Сам тоже потом читал.
В том числе: Шаблон репозитория.

Модель работает с отдельными узлами агрегации (?) Contacts и Phones.
По сути не важно какое в каждом из них используется хранилище.
И я задумался над тем можно ли их сделать полностью независимыми, в отдельных сборках.
В модель будут передаваться только экземпляры Contacts и Phones.
А как там они уже внутри реализованы для модели не важно.

Так же не должно быть важно для Contacts как реализован Phones и наоборот.
Каждый из них получает в параметрах БД с которой будет работать (или локальный xml-файл в других реализациях) и этого должно быть достаточно.
Но тогда контекст у них должен быть у каждого свой:
C#
1
2
3
4
5
6
7
8
9
    public class ContactsDB : DbContext
    {
        public ContactsDB(????)
            : base(????)
        {
 
        }
        public DbSet<ContactEntity> Contacts { get; set; }
    }
C#
1
2
3
4
5
6
7
8
9
    public class PhonesDB : DbContext
    {
        public ContactsDB(????)
            : base(????)
        {
 
        }
        public DbSet<PhoneEntity> Phones{ get; set; }
    }
При этом возникает (у меня) вопрос: что будет, если в параметрах указать одну и туже БД?
Если БД уже создана с общей архитектурой, то проблем, насколько понимаю, быть не должно.
А вот, что будет если БД нет и её должен создать Code First?

Первым был вызван ContactsDB - он создаст БД со своей таблицей.
Потом будет вызван PhonesDB. БД уже есть, но в ней нет нужной таблицы.
Code First добавит нужную таблицу или будет какая-то ошибка?

Цитата Сообщение от Usaga Посмотреть сообщение
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Но вот Code First (насколько разобрался) в нём (System.Data) нет.
Code First есть. Механизмов миграций для SQLite там нет.
Вот здесь я воще не в зуб ногой.
Ху из ху?

Но с System.Data ещё и проблема с подтягиванием зависимостей.
Мы тоже один раз с вами уже этим занимались.
При установке System.Data в сборке репозитория и потом использовании его в в основном проекте Решения, в него подтягивается System.Data, но не подтягиваются какие-то зависимые пакеты.
И приходится в основной проекте тоже явно устанавливать полностью Nuget System.Data.

Цитата Сообщение от Usaga Посмотреть сообщение
Насчёт создания базы, если её нет. Вам для этого EF вообще не обязателен. Вы можете:
Цель максимально воспользоваться дефолтными инструментами и минимальным "ручным кодом".
У меня все задачи учебные.
Какие-то для самообучения, какие-то для обучения кого-то.
Поэтому задача изучить как сделать вот таким-то образом, чтобы потом можно было осознано выбирать как лучше.

В данном случае Решение не моё.
В нем реализована работа с БД через конекторы, адаптеры, SQL команды и тд.
Репозиторий даже не выделен в отдельный проект.
Вот мне стало интересно изучить как это можно сделать по феншую и с минимальным ручным кодированием.

Добавлено через 18 минут
Цитата Сообщение от Usaga Посмотреть сообщение
Эта связка не будет работать последние две или три версии EF Core работают только на .NET Core.
Поставил Microsoft.EntityFrameworkCore.Sqlite 3.1.19.

Сразу вопрос об атрибуте [Indeх] - его нет ни в одном пакете Nuget (из указанных в названии темы).
Как быть с ним?
0
Модератор
Эксперт .NET
15468 / 10713 / 2787
Регистрация: 21.04.2018
Сообщений: 31,536
Записей в блоге: 2
23.09.2021, 10:46  [ТС] 6
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Поставил Microsoft.EntityFrameworkCore.Sqlite 3.1.19.
Задал такой контекст:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    public class ContactDB : DbContext
    {
        public ContactDB(string pathAndNameDB)
            : base()
        {
 
            PathAndNameDB = pathAndNameDB;
        }
 
 
        protected override void OnConfiguring(DbContextOptionsBuilder options)
            => options.UseSqlite($"Data Source={PathAndNameDB}");
 
        public string PathAndNameDB { get; }
        public DbSet<ContactEntity> Contacts { get; set; }
        public DbSet<PhoneEntity> Phones { get; set; }
 
    }
БД создаётся, но без таблиц.
0
HF
1163 / 749 / 181
Регистрация: 09.09.2011
Сообщений: 2,314
Записей в блоге: 2
23.09.2021, 11:02 7
Что-то вы капец наворочали. И то и другое и третье. Вы можете озвучить ваше приоритетное желание и проблему которая мешает этой реализации? Потому что не понятно как ответить. У вас на каждый абзац можно дать разный ответ, так как подходы будут разные.

Ещё раз повторюсь - если вы используете EF, то всё. Пользуйтесь тем что он предоставляет и всё что с этим связано. Есть пакеты миграций баз. Само оно не работает как надо. Всё равно все, в итоге, пишут надстройку.

Мы, с Usaga, вам посоветовали - пишите свой мигратор. По структуре это: 1) набор скриптов, начиная от создания таблиц, и далее как обычно добавления, обновления структур и данных. 2) метод в коде который будет запускать сервис который будет создавать файл (или считывать существующий) и накатывать нужные обновления. Это простейший метод - читаем файл как текст, вызываем запрос.

Про модели.
Если "в нем реализована работа с БД через конекторы, адаптеры, SQL команды и тд.", то нужно представлять что именно и как там реализовано. Изначально, вы не сможете сделать универсальный репозиторий. У вас будет на каждую таблицу свой репозиторий с захардкоженными запросами на каждый метод.
Если хотите сделать генерик репозиторий с LINQ запросами - SQLite.NET. Он на это "заточен".

Про контекст. Исходя из реализации репозиториев будет понятно какой сложности контекст.
Но раз вы сказали про разные БД, то - UoW вам в помощь. Именно так я сразу сделал свой контекст. Даже с одной БД, можно реализовать контекст сложных репозиториев, которые могут быть как генерик, так и типизированные.
0
295 / 119 / 33
Регистрация: 06.03.2016
Сообщений: 453
23.09.2021, 11:42 8
Цитата Сообщение от Элд Хасп Посмотреть сообщение
БД создаётся, но без таблиц.
C#
1
2
3
4
5
public ContactDB(string pathAndNameDB) : base()
{
    PathAndNameDB = pathAndNameDB;
    Database.EnsureCreated();
}
1
Эксперт .NET
12083 / 8391 / 1283
Регистрация: 21.01.2016
Сообщений: 31,636
23.09.2021, 14:12 9
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Модель работает с отдельными узлами агрегации (?) Contacts и Phones.
По сути не важно какое в каждом из них используется хранилище.
И я задумался над тем можно ли их сделать полностью независимыми, в отдельных сборках.
В модель будут передаваться только экземпляры Contacts и Phones.
А как там они уже внутри реализованы для модели не важно.
Опять же, муть какая-то) Вы в репозиторий передаёте экземпляр контекста и работаете в нём с любыми нужными сущностями. Про независимые сборки я не понял. Звучит как оверинжиниринг.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Так же не должно быть важно для Contacts как реализован Phones и наоборот.
Каждый из них получает в параметрах БД с которой будет работать (или локальный xml-файл в других реализациях) и этого должно быть достаточно.
Но тогда контекст у них должен быть у каждого свой:
А вот это уже точно фигня полная. Не городите огороды. Один контекст на базу и всё. Репозиторий обратится к тем сущностям, к которым ему нужно. В нормальных условиях это будет не одна корреная сущность, но может быть целая россыпь. Не надо тут контексты кастрированные городить. Тем более, что в рамках одной транзакции это приведёт к нехорошим последствиям для производительности (не только для архитектуры приложения).

Цитата Сообщение от Элд Хасп Посмотреть сообщение
Сразу вопрос об атрибуте [Indeх] - его нет ни в одном пакете Nuget (из указанных в названии темы).
Как быть с ним?
Скорее всего он в сборке с самим EF, а не в сборке с провайдером для SQLite.

Добавлено через 3 минуты
Цитата Сообщение от Элд Хасп Посмотреть сообщение
У меня все задачи учебные.
Тогда ваш путь таков:
Цитата Сообщение от HF Посмотреть сообщение
Мы, с Usaga, вам посоветовали - пишите свой мигратор.
Обучаетесь работе с СУБД "с низов". Потом уже для себя решаете, нужны вам какие-то инструменты поверх всего этого или нет.

Я не против того, что вы взяли EF для работы (конечно же это наглая ложь). Но ещё и миграции на эту штуку взвешивать... Вот это точно не учебный подход. Тем более, что у вас уже с ним проблемы начали, с поиском атрибутов для индексов).

Но миграции тут мелочь, на самом деле. Вот попытка нагородить огороды в DAL с кучами контекстов специфичных для репозиториев меня реально опешила)
2
1496 / 1238 / 244
Регистрация: 04.04.2011
Сообщений: 4,362
23.09.2021, 16:16 10
I. На мой непросвещенный взгляд, у EF есть только два достоинства:
1. Иллюзия "быстрой" разработки приложений для работы с СУБД (для новичков).
2. Способность при простом коде выполнять множественные изменения в БД в разных таблицах в контексте единой транзакции (реально эффективно даже для опытных разработчиков).

Если второе не нужно, EF в топку !

II. Выноска всей логики работы в БД в репозиторий. Основной код приложения ничего не должен знать о том, какой сервер, где он и вообще что там делается. Работа идет с моделями, получение их и правка в БД - все в репозитории !

III. Создание БД и миграция данных.
Пишется метод в репозитории CreateMyDataBase, в котором проверяется наличие БД и, если ее нет, то она создается и в нее записывается единственная хранимка (см. далее) из текстового файла в установочном пакете.
Пишется метод в репозитории CreateMyDataBaseInstance, в котором проверяется наличие данных в БД, включая метаданные о таблицах и прочие. Если таблиц нет, то запускается вышеупомянутая хранимка. Предусмотреть опцию пересоздания БД даже если есть таблицы.
Хранимка уничтожает таблицы, если они есть, создает их по новой, после чего заполняет отладочными данными либо выполняет заливку их из сторонних источников, например из другой (других) БД либо из csv, положенных в установочный пакет.
1
Эксперт .NET
12083 / 8391 / 1283
Регистрация: 21.01.2016
Сообщений: 31,636
23.09.2021, 17:51 11
Цитата Сообщение от MsGuns Посмотреть сообщение
2. Способность при простом коде выполнять множественные изменения в БД в разных таблицах в контексте единой транзакции (реально эффективно даже для опытных разработчиков).
Эта фича стоит дорого, на самом деле. В плане потребления ресурсов. Оно со стороны эффектно и круто выглядит только.
0
1496 / 1238 / 244
Регистрация: 04.04.2011
Сообщений: 4,362
23.09.2021, 18:49 12
Usaga, За простоту и "читабельность" алгоритмики нужно платить ресурсами и производительностью.
А за производительность и экономию ресурсов платить сложным громоздким кодом.

Искусство программирования заключается в нахождении оптимального компромисса
0
Эксперт .NET
12083 / 8391 / 1283
Регистрация: 21.01.2016
Сообщений: 31,636
24.09.2021, 05:59 13
MsGuns, ну так да) Единственное, что громоздкий код не всегда сложен для понимания и написания)
0
Модератор
Эксперт .NET
15468 / 10713 / 2787
Регистрация: 21.04.2018
Сообщений: 31,536
Записей в блоге: 2
24.09.2021, 11:32  [ТС] 14
Usaga, MsGuns, ipsorokin, HF, всем спасибо!
Извиняюсь за:
Цитата Сообщение от HF Посмотреть сообщение
Что-то вы капец наворочали
Это по причине большого сумбура в моей голове.
Попробую привести его немного в порядок и потом более конкретизирую свои вопросы.
0
Эксперт .NET
12083 / 8391 / 1283
Регистрация: 21.01.2016
Сообщений: 31,636
24.09.2021, 11:34 15
Элд Хасп, совет: сделайте максимально просто. А потом уже пытайтесь рефакторить в сторону порядка. Попытки продумать архитектуру заранее, не имея опыта, приведут к ещё большему сумбуру.
1
1496 / 1238 / 244
Регистрация: 04.04.2011
Сообщений: 4,362
24.09.2021, 12:36 16
Цитата Сообщение от Usaga Посмотреть сообщение
совет: сделайте максимально просто. А потом уже пытайтесь рефакторить в сторону порядка. Попытки продумать архитектуру заранее, не имея опыта, приведут к ещё большему сумбуру.
С языка сорвал
0
Модератор
Эксперт .NET
15468 / 10713 / 2787
Регистрация: 21.04.2018
Сообщений: 31,536
Записей в блоге: 2
24.09.2021, 12:37  [ТС] 17
Цитата Сообщение от Usaga Посмотреть сообщение
сделайте максимально просто. А потом уже пытайтесь рефакторить в сторону порядка. Попытки продумать архитектуру заранее, не имея опыта, приведут к ещё большему сумбуру.
Сделать "Просто" - я с ваши (всех кто принял участие) подсказками смог.
Сейчас сделано на Microsoft.EntityFrameworkCore.Sqlite 3.1.19 вот так (пример):
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
    public class ContactsDB : DbContext
    {
        public ContactsDB(string pathAndNameDB)
            : base()
        {
 
            PathAndNameDB = pathAndNameDB;
            if (!File.Exists(pathAndNameDB))
            {
                string folder = Path.GetDirectoryName(pathAndNameDB);
                if (!string.IsNullOrEmpty(folder) && !Directory.Exists(folder))
                {
                    DirectoryInfo directory = Directory.CreateDirectory(folder);
                    pathAndNameDB = Path.Combine(directory.FullName, Path.GetFileName(pathAndNameDB));
                    PathAndNameDB = pathAndNameDB;
                }
                Database.EnsureCreated();
            }
        }
 
 
        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlite($"Data Source={PathAndNameDB}");
        }
 
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<ContactEntity>().HasData(GetDefaultContacts());
            modelBuilder.Entity<PhoneEntity>().HasData(GetDefaultPhones());
 
            base.OnModelCreating(modelBuilder);
        }
 
        private ContactEntity[] GetDefaultContacts()
        {
            return new ContactEntity[]
            {
                new ContactEntity() {Id = 123, Name="Сергей (Exampl)"},
                new ContactEntity() {Id = 567, Name="Алексей (Exampl)"}
            };
        }
        private PhoneEntity[] GetDefaultPhones()
        {
            return new PhoneEntity[]
            {
                new PhoneEntity() {Id = 9, ContactId = 123,  Title="Пожарная", Number="01"},
                new PhoneEntity() {Id = 23, ContactId = 567,  Title="Полиция", Number="02"},
                new PhoneEntity() {Id = 87, ContactId = 123,  Title="Скорая", Number="03"},
                new PhoneEntity() {Id = 54, ContactId = 567,  Title="МЧС", Number="112"}
            };
        }
 
        public string PathAndNameDB { get; }
        public DbSet<ContactEntity> Contacts { get; set; }
        public DbSet<PhoneEntity> Phones { get; set; }
 
    }
Тест примера:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
        static void Main(string[] args)
        {
            string dbName = "DataBases/contacs.db";
 
            Console.Write("Удалить базу и папку? (Y + Enter): ");
            if (Console.ReadLine().ToUpper() == "Y")
            {
                // Удаление  бызы и папки если они есть
                if (File.Exists(dbName))
                    File.Delete(dbName);
 
                var folder = Path.GetDirectoryName(dbName);
                if (Directory.Exists(folder))
                    Directory.Delete(folder);
            }
 
            // Запрос к базе. При первом запросе, если нет базы,
            // то она автоматически создаётся и
            // заполняется данными для примера.
            List<ContactEntity> contacts;
            using (var db = new ContactsDB(dbName))
                contacts = db.Contacts.ToList();
            Console.WriteLine(string.Join(Environment.NewLine, contacts.Select(c => $"{c.Id}: {c.Name}")));
 
            // Добавление одной записи
            Console.WriteLine();
            var contact = new ContactEntity() { Name = "Борис" };
            using (var db = new ContactsDB(dbName))
            {
                db.Contacts.Add(contact);
                db.SaveChanges();
                contacts = db.Contacts.ToList();
            }
            Console.WriteLine(string.Join(Environment.NewLine, contacts.Select(c => $"{c.Id}: {c.Name}")));
 
            // Изменение одной записи
            Console.WriteLine();
            using (var db = new ContactsDB(dbName))
            {
                contact = db.Contacts.Find(567);
                contact.Name = "Иванов Иван Иваныч";
                db.SaveChanges();
                contacts = db.Contacts.ToList();
            };
            Console.WriteLine(string.Join(Environment.NewLine, contacts.Select(c => $"{c.Id}: {c.Name}")));
 
            // Вывод с фильтрацией
            Console.WriteLine();
            List<PhoneEntity> phones;
            using (var db = new ContactsDB(dbName))
                phones = db.Phones.Where(ph => ph.ContactId == 567).ToList();
 
            Console.WriteLine(string.Join(Environment.NewLine, phones.Select(ph => $"{ph.ContactId}-{ph.Id} {ph.Title}: {ph.Number}")));
 
        }
Для меня это учебно-познавательный проект.
Но возник он из реальной (не моей) задачи.
Так же вроде решили всё же перейти с FW на Core.

После перехода на Core, потестирую в нём и посмотрю какие вопросы смогу решить сам, а какие нет и конкретизирую их здесь.

У меня "душа" лежит за Sysytem.Data.SQLite.
Но у него проблемы с вытягиванием зависимостей репозитория в основной проект Решения.
Мы с вами уже разбирались с этим.
И самым простым решением оказалось двойная установка этого пакета в проекте Репозитория и в Основном Проекте.
Возможно после перехода на Core он станет нормально тянуть зависимости и тогда вопрос выбора пакетов отпадёт.
0
Эксперт .NET
12083 / 8391 / 1283
Регистрация: 21.01.2016
Сообщений: 31,636
24.09.2021, 13:05 18
Элд Хасп, не надо так:

C#
1
2
3
4
5
6
7
8
9
10
11
12
            PathAndNameDB = pathAndNameDB;
            if (!File.Exists(pathAndNameDB))
            {
                string folder = Path.GetDirectoryName(pathAndNameDB);
                if (!string.IsNullOrEmpty(folder) && !Directory.Exists(folder))
                {
                    DirectoryInfo directory = Directory.CreateDirectory(folder);
                    pathAndNameDB = Path.Combine(directory.FullName, Path.GetFileName(pathAndNameDB));
                    PathAndNameDB = pathAndNameDB;
                }
                Database.EnsureCreated();
            }
По идее, одного Database.EnsureCreated() должно быть достаточно. Вроде бы EF Core уже сам умеет базу создавать. Проверьте. Если нет, то вынисите эту байду в статический конструктор, чтобы один раз отрабатывало, при запуске приложения, а не при каждом создании контекста.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
public string PathAndNameDB { get; }
Тоже лишнее.

Цитата Сообщение от Элд Хасп Посмотреть сообщение
if (Console.ReadLine().ToUpper() == "Y")
C#
1
if ("Y".Equals(Console.ReadLine(), StringComparison.InvariantCultureIgnoreCase))
Зачем стопятьсот раз контекст в рамках одного метода создавать?))) Можно и один раз)
0
295 / 119 / 33
Регистрация: 06.03.2016
Сообщений: 453
24.09.2021, 14:20 19
Цитата Сообщение от Usaga Посмотреть сообщение
По идее, одного Database.EnsureCreated() должно быть достаточно. Вроде бы EF Core уже сам умеет базу создавать.
Так и есть.
0
Модератор
Эксперт .NET
15468 / 10713 / 2787
Регистрация: 21.04.2018
Сообщений: 31,536
Записей в блоге: 2
24.09.2021, 14:25  [ТС] 20
Цитата Сообщение от Usaga Посмотреть сообщение
Вроде бы EF Core уже сам умеет базу создавать.
Он БД может создавать, но не может создавать папку.
Поэтому папку я создаю дискретным кодом.
А БД в ней создаёт уже Database.EnsureCreated().

Добавлено через 5 минут
Цитата Сообщение от ipsorokin Посмотреть сообщение
Так и есть.
Если закомментировать код создания папки, то вот такое исключение:
Microsoft.Data.Sqlite.SqliteException
HResult=0x80004005
Сообщение = SQLite Error 14: 'unable to open database file'.
Источник = Microsoft.Data.Sqlite
Трассировка стека:
в Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(Int32 rc, sqlite3 db)
в Microsoft.Data.Sqlite.SqliteConnection.Open()
в Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(Bool ean errorsExpected)
в Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(Boolean errorsExpected)
в Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal.SqliteDatabaseCreator.Crea te()
в Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.EnsureCreated()
в Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.EnsureCreated()
в EFExample.ContactsDB..ctor(String pathAndNameDB) в C:\Users\EldHa\Мои проекты\Проекты-Помогалки\Ametist(Git-stelsbrest)\TestExamplesSln\EFExample\ContactsDB.cs:строка 23
в EFExample.Program.Main(String[] args) в C:\Users\EldHa\Мои проекты\Проекты-Помогалки\Ametist(Git-stelsbrest)\TestExamplesSln\EFExample\Program.cs:строка 30

Изначально это исключение было создано в этом стеке вызовов:
Microsoft.Data.Sqlite.SqliteException.ThrowExceptionForRC(int, SQLitePCL.sqlite3)
Microsoft.Data.Sqlite.SqliteConnection.Open()
Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnection(bool )
Microsoft.EntityFrameworkCore.Storage.RelationalConnection.Open(bool)
Microsoft.EntityFrameworkCore.Sqlite.Storage.Internal.SqliteDatabaseCreator.Crea te()
Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.EnsureCreated()
Microsoft.EntityFrameworkCore.Infrastructure.DatabaseFacade.EnsureCreated()
EFExample.ContactsDB.ContactsDB(string) в ContactsDB.cs
EFExample.Program.Main(string[]) в Program.cs
Миниатюры
Code First - выбор: Microsoft.EntityFrameworkCore.Sqlite, Microsoft.Data.Sqlite, System.Data.SQLite и др.  
0
24.09.2021, 14:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.09.2021, 14:25
Помогаю со студенческими работами здесь

Не могу подключиться к SQLlite (Could not load file or assembly 'System.Data.SQLite)
Хочу приконнектиться к базе на sqllite, скачал библиотеку нужную для sqllite отсюда:...

Не работает проверка существования таблицы через метод ExecuteNonQuery() из System.Data.SQLite.dll
Использую приведенный ниже метод для определения существования таблицы в БД public int...

программа подключается к базе (Firebird, SQLite) только на компе с Microsoft Visual C#
Подскажите, пожалуйста, как разобраться. Программа подключается к базе (Firebird, SQLite) только...

Редактирование связанных объектов через EF в SQLite, C#, EF 6.2, SQLite, C# Winforms
Здравствуйте. Суть: используя вышеперечисленные технологии, при чтении из базы данных связанных...

Изменить базу данных с MySQL на SQLite в проекте с Entity Framework code first
Добрый день, подскажите пожалуйста: Имеется проект C# приложение windows form с entity framework...

MS SQL Необработанное исключение типа "System.Data.SqlClient.SqlException" в System.Data.dll
Что не так? Необработанное исключение типа &quot;System.Data.SqlClient.SqlException&quot; в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru