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

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

22.09.2021, 19:48. Показов 11542. Ответов 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
1234 / 822 / 189
Регистрация: 09.09.2011
Сообщений: 2,481
Записей в блоге: 2
22.09.2021, 23:40
Если DbContext нужен - то разумеется только EF.
Если нужен лёгкий сервис без извращений - оригинальный System.Data.SQLite. Будет только 1 либа (+1 в нагрузку).
Microsoft.Data.Sqlite - это середнячок от микрософта, но он по сути - аналог оригинальной.

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

Я использую чистый.
"Репозиторий" сделал сам, или можно использовать SQLite.Net пакет, он чуть больше умеет.
Создание таблиц и миграции тоже сам написал в реализации - набор файлов скриптов и автовыполнение их при необходимости. Удобно - эти же файлы можно руками запускать.
1
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16013 / 11150 / 2869
Регистрация: 21.04.2018
Сообщений: 32,766
Записей в блоге: 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
13481 / 9013 / 1326
Регистрация: 21.01.2016
Сообщений: 33,824
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
 Аватар для Элд Хасп
16013 / 11150 / 2869
Регистрация: 21.04.2018
Сообщений: 32,766
Записей в блоге: 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
 Аватар для Элд Хасп
16013 / 11150 / 2869
Регистрация: 21.04.2018
Сообщений: 32,766
Записей в блоге: 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
1234 / 822 / 189
Регистрация: 09.09.2011
Сообщений: 2,481
Записей в блоге: 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
13481 / 9013 / 1326
Регистрация: 21.01.2016
Сообщений: 33,824
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
13481 / 9013 / 1326
Регистрация: 21.01.2016
Сообщений: 33,824
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
13481 / 9013 / 1326
Регистрация: 21.01.2016
Сообщений: 33,824
24.09.2021, 05:59
MsGuns, ну так да) Единственное, что громоздкий код не всегда сложен для понимания и написания)
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16013 / 11150 / 2869
Регистрация: 21.04.2018
Сообщений: 32,766
Записей в блоге: 2
24.09.2021, 11:32  [ТС]
Usaga, MsGuns, ipsorokin, HF, всем спасибо!
Извиняюсь за:
Цитата Сообщение от HF Посмотреть сообщение
Что-то вы капец наворочали
Это по причине большого сумбура в моей голове.
Попробую привести его немного в порядок и потом более конкретизирую свои вопросы.
0
Эксперт .NET
 Аватар для Usaga
13481 / 9013 / 1326
Регистрация: 21.01.2016
Сообщений: 33,824
24.09.2021, 11:34
Элд Хасп, совет: сделайте максимально просто. А потом уже пытайтесь рефакторить в сторону порядка. Попытки продумать архитектуру заранее, не имея опыта, приведут к ещё большему сумбуру.
1
1497 / 1238 / 245
Регистрация: 04.04.2011
Сообщений: 4,363
24.09.2021, 12:36
Цитата Сообщение от Usaga Посмотреть сообщение
совет: сделайте максимально просто. А потом уже пытайтесь рефакторить в сторону порядка. Попытки продумать архитектуру заранее, не имея опыта, приведут к ещё большему сумбуру.
С языка сорвал
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16013 / 11150 / 2869
Регистрация: 21.04.2018
Сообщений: 32,766
Записей в блоге: 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
13481 / 9013 / 1326
Регистрация: 21.01.2016
Сообщений: 33,824
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
 Аватар для Элд Хасп
16013 / 11150 / 2869
Регистрация: 21.04.2018
Сообщений: 32,766
Записей в блоге: 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
Ответ Создать тему
Новые блоги и статьи
Создаем RESTful API на Golang с Fiber
golander 04.06.2025
Я перепробовал десятки фреймворков для создания RESTful API за последние годы, и когда впервые столкнулся с Fiber, понял, что это совсем другой уровень. Нет, я не собираюсь рассказывать сказки о. . .
Как работать с куки в ASP.NET Core
UnmanagedCoder 04.06.2025
Когда я впервые начал работать с куки в ASP. NET Core, меня поразило, насколько отличается работа с ними от классического ASP. NET. В Core все стало более декомпозированным - больше нет удобного. . .
Рисование коллайдеров физического движка Box2D-WASM v3 на Three.js
8Observer8 04.06.2025
Erin Catto (автор Box2D) переписал с нуля Box2D v2 с С++ на Си и появилась версия Box2D v3. Birch-san собрал Box2D v3 в WebAssembly (WASM), чтобы можно было использовать Box2D v3 на JavaScript. В. . .
Worker Threads и многопоточность в Node.js
Reangularity 03.06.2025
Если вы когда-нибудь посещали собеседования на позицию Node. js разработчика, почти наверняка слышали заезженную фразу: "Node. js - однопоточная платформа". Звучит как неоспоримый факт, который. . .
Event-Driven CQRS на C# с паттерном Outbox
stackOverflow 03.06.2025
В традиционной модели происходит примерно следующее: вы получаете команду, обрабатываете ее, сохраняете результат в базу данных и затем пытаетесь опубликовать событие в брокер сообщений. Но что если. . .
OwenLogic: перенос сетевых переменных в панель Weintek (EasyBuilder Pro)
ФедосеевПавел 03.06.2025
ВВЕДЕНИЕ ПЕРЕД ЭКСПЕРИМЕНТАМИ - СОЗДАЙТЕ РЕЗЕРВНЫЕ КОПИИ ПРОЕКТОВ На момент написания статьи (02 июня 2025 г. ) самыми актуальными версиями ПО являются: OwenLogic v. 2. 10. 366 EasyBuilder Pro. . .
Dev-c++5.11 Покорение вершины
russiannick 02.06.2025
С утра преследовала одна мысль - вот бы выучить С++. Сказано-сделано. Окончив смену, скачал в интернете бестселлер Дэвиса Dev-C++ для чайников. Книга оказалась интересной и я скачал среду, на примере. . .
Тестирование Pull Request в Kubernetes с GitHub Actions и GKE
Mr. Docker 02.06.2025
Мы все знаем, что тестирование на локальной машине или в изолированном CI-окружении — это не совсем то же самое, что тестирование в реальном кластере Kubernetes. Контекстно-зависимые ошибки, проблемы. . .
Оптимизация CMake для ускорения сборки
bytestream 02.06.2025
Вы когда-нибудь ловили себя на мысле, что пока ваш проект компилируется, можно успеть сварить кофе, прочитать главу книги или даже сбегать в соседний офис? Если да, то добро пожаловать в клуб. . .
JS String.prototype.localeCo­mpare()
mr_dramm 02.06.2025
скопировано из этой темы чтобы не потерялось. localeCompare без указания локали для сравнения строк под капотом использует Intl. Collator , который работает согласно Unicode Collation Algorithm. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
OSZAR »