Форум программистов, компьютерный форум, киберфорум
C#: Базы данных
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.82/55: Рейтинг темы: голосов - 55, средняя оценка - 4.82
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16116 / 11237 / 2887
Регистрация: 21.04.2018
Сообщений: 33,038
Записей в блоге: 2
SQLite

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

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

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

Стоит задача в Решении 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
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
22.09.2021, 19:48
Ответы с готовыми решениями:

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

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

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

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

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

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


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

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

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

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

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

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

Я бы выбирал из этих двух вариантов, а не налегал бы на возможности миграции EF'а.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16116 / 11237 / 2887
Регистрация: 21.04.2018
Сообщений: 33,038
Записей в блоге: 2
23.09.2021, 10:06  [ТС]
Цитата Сообщение от 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
 Аватар для Элд Хасп
16116 / 11237 / 2887
Регистрация: 21.04.2018
Сообщений: 33,038
Записей в блоге: 2
23.09.2021, 10:46  [ТС]
Цитата Сообщение от Элд Хасп Посмотреть сообщение
Поставил 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
 Аватар для HF
1303 / 882 / 199
Регистрация: 09.09.2011
Сообщений: 2,590
Записей в блоге: 2
23.09.2021, 11:02
Что-то вы капец наворочали. И то и другое и третье. Вы можете озвучить ваше приоритетное желание и проблему которая мешает этой реализации? Потому что не понятно как ответить. У вас на каждый абзац можно дать разный ответ, так как подходы будут разные.

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

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

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

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

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

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

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

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

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

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

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

III. Создание БД и миграция данных.
Пишется метод в репозитории CreateMyDataBase, в котором проверяется наличие БД и, если ее нет, то она создается и в нее записывается единственная хранимка (см. далее) из текстового файла в установочном пакете.
Пишется метод в репозитории CreateMyDataBaseInstance, в котором проверяется наличие данных в БД, включая метаданные о таблицах и прочие. Если таблиц нет, то запускается вышеупомянутая хранимка. Предусмотреть опцию пересоздания БД даже если есть таблицы.
Хранимка уничтожает таблицы, если они есть, создает их по новой, после чего заполняет отладочными данными либо выполняет заливку их из сторонних источников, например из другой (других) БД либо из csv, положенных в установочный пакет.
1
Эксперт .NET
 Аватар для Usaga
14087 / 9305 / 1348
Регистрация: 21.01.2016
Сообщений: 34,932
23.09.2021, 17:51
Цитата Сообщение от MsGuns Посмотреть сообщение
2. Способность при простом коде выполнять множественные изменения в БД в разных таблицах в контексте единой транзакции (реально эффективно даже для опытных разработчиков).
Эта фича стоит дорого, на самом деле. В плане потребления ресурсов. Оно со стороны эффектно и круто выглядит только.
0
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
23.09.2021, 18:49
Usaga, За простоту и "читабельность" алгоритмики нужно платить ресурсами и производительностью.
А за производительность и экономию ресурсов платить сложным громоздким кодом.

Искусство программирования заключается в нахождении оптимального компромисса
0
Эксперт .NET
 Аватар для Usaga
14087 / 9305 / 1348
Регистрация: 21.01.2016
Сообщений: 34,932
24.09.2021, 05:59
MsGuns, ну так да) Единственное, что громоздкий код не всегда сложен для понимания и написания)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16116 / 11237 / 2887
Регистрация: 21.04.2018
Сообщений: 33,038
Записей в блоге: 2
24.09.2021, 11:32  [ТС]
Usaga, MsGuns, ipsorokin, HF, всем спасибо!
Извиняюсь за:
Цитата Сообщение от HF Посмотреть сообщение
Что-то вы капец наворочали
Это по причине большого сумбура в моей голове.
Попробую привести его немного в порядок и потом более конкретизирую свои вопросы.
0
Эксперт .NET
 Аватар для Usaga
14087 / 9305 / 1348
Регистрация: 21.01.2016
Сообщений: 34,932
24.09.2021, 11:34
Элд Хасп, совет: сделайте максимально просто. А потом уже пытайтесь рефакторить в сторону порядка. Попытки продумать архитектуру заранее, не имея опыта, приведут к ещё большему сумбуру.
1
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
24.09.2021, 12:36
Цитата Сообщение от Usaga Посмотреть сообщение
совет: сделайте максимально просто. А потом уже пытайтесь рефакторить в сторону порядка. Попытки продумать архитектуру заранее, не имея опыта, приведут к ещё большему сумбуру.
С языка сорвал
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16116 / 11237 / 2887
Регистрация: 21.04.2018
Сообщений: 33,038
Записей в блоге: 2
24.09.2021, 12:37  [ТС]
Цитата Сообщение от 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
 Аватар для Usaga
14087 / 9305 / 1348
Регистрация: 21.01.2016
Сообщений: 34,932
24.09.2021, 13:05
Элд Хасп, не надо так:

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
296 / 120 / 33
Регистрация: 06.03.2016
Сообщений: 453
24.09.2021, 14:20
Цитата Сообщение от Usaga Посмотреть сообщение
По идее, одного Database.EnsureCreated() должно быть достаточно. Вроде бы EF Core уже сам умеет базу создавать.
Так и есть.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16116 / 11237 / 2887
Регистрация: 21.04.2018
Сообщений: 33,038
Записей в блоге: 2
24.09.2021, 14:25  [ТС]
Цитата Сообщение от 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.Th rowExceptionForRC(Int32 rc, sqlite3 db)
в Microsoft.Data.Sqlite.SqliteConnection.O pen()
в Microsoft.EntityFrameworkCore.Storage.Re lationalConnection.OpenDbConnection(Bool ean errorsExpected)
в Microsoft.EntityFrameworkCore.Storage.Re lationalConnection.Open(Boolean errorsExpected)
в Microsoft.EntityFrameworkCore.Sqlite.Sto rage.Internal.SqliteDatabaseCreator.Crea te()
в Microsoft.EntityFrameworkCore.Storage.Re lationalDatabaseCreator.EnsureCreated()
в Microsoft.EntityFrameworkCore.Infrastruc ture.DatabaseFacade.EnsureCreated()
в EFExample.ContactsDB..ctor(String pathAndNameDB) в C:\Users\EldHa\Мои проекты\Проекты-Помогалки\Ametist(Git-stelsbrest)\TestExamplesSln\EFExample\Co ntactsDB.cs:строка 23
в EFExample.Program.Main(String[] args) в C:\Users\EldHa\Мои проекты\Проекты-Помогалки\Ametist(Git-stelsbrest)\TestExamplesSln\EFExample\Pr ogram.cs:строка 30

Изначально это исключение было создано в этом стеке вызовов:
Microsoft.Data.Sqlite.SqliteException.Th rowExceptionForRC(int, SQLitePCL.sqlite3)
Microsoft.Data.Sqlite.SqliteConnection.O pen()
Microsoft.EntityFrameworkCore.Storage.Re lationalConnection.OpenDbConnection(bool )
Microsoft.EntityFrameworkCore.Storage.Re lationalConnection.Open(bool)
Microsoft.EntityFrameworkCore.Sqlite.Sto rage.Internal.SqliteDatabaseCreator.Crea te()
Microsoft.EntityFrameworkCore.Storage.Re lationalDatabaseCreator.EnsureCreated()
Microsoft.EntityFrameworkCore.Infrastruc ture.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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
24.09.2021, 14:25
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru