EF Core. scaffold-dbcontext. DBFirst
Есть таблица
CREATE TABLE [dbo].[Orders] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[UserId] INT NOT NULL,
[IsProcessed] BIT DEFAULT (CONVERT([bit],(0))) NOT NULL,
CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Создаю классы вызывая при помощи Scaffold-DbContext (DBFirst):
автор |
---|
PM> Scaffold-DbContext "Server=(localdb)\mssqllocaldb; Database=TestDb; Trusted_Connection=true;" Microsoft.EntityFrameworkCore.SqlServer Build started... Build succeeded. To protect potentially sensitive information in your connection string, you should move it out of source code. You can avoid scaffolding the connection string by using the Name= syntax to read it from configuration - see https://go.microsoft.com/fwlink/?linkid=2131148. For more guidance on storing connection strings, see http://go.microsoft.com/fwlink/?LinkId=723263. The column 'dbo.Orders.IsProcessed' would normally be mapped to a non-nullable bool property, but it has a default constraint. Such a column is mapped to a nullable bool property to allow a difference between setting the property to false and invoking the default constraint. See https://go.microsoft.com/fwlink/?linkid=851278 for details. |
Создается класс:
public partial class Order
{
public int Id { get; set; }
public int UserId { get; set; }
public bool? IsProcessed { get; set; }
}
Изначально поле в таблице было не нулевым, а в классе создается нулевым.
Такая особенность и как с этим бороться не понятно. Править каждый раз в ручную, при наличае более 15 классов не хочется. Есть ли какие-нибудь соображения по этому поводу?
Можно ещё сюда глянуть - там в первом ответе
Scaffold mapping on non-nullable bool · Issue #10840 · dotnet/efcore · GitHub
Было бы EF Code First, то такой проблемы бы не было. Кроме того, Code First это готовый как бы скрипт по созданию базы данных. И миграции потом тоже на нём же (Code First) писать можно. И если проект разрабатывается с приоритетом в код на Шарпе - т.е. шарповский код первичен и на нём делается главная модель приложения, то и хранилище (БД) тоже логичнее генерить из шарповских моделей - максимально близко к главной модели. Потому что реляционная модель БД и ООП не маппятся друг на друга со 100% совместимостью.
> и хранилище (БД) тоже логичнее генерить из шарповских моделей
-----
Да-да, конечно...
Специфицируй, плс, в шарповой модели... триггер.
А когда специфицируешь - добейся чтобы база его компилировала однократно...
Да, забыл... есть такая ерунда как расширения для МС СКЛ сервера - пишешь сборку, втыкаешь в сервер и юзаешь функциональность.
Недавно Я тут задавал вопросик про пару СКЛ запросов - один из вариантов решения - написать такую сборку... токма там не МС СКЛ, а Постгрее...
Ну и как ты будешь ЭТО генерить из шарповой модели?
------
Я слегка поизвращаюсь?
Насчет Коре - не уверн, не работал.
Для обычного проекта...
В проекте есть два набора команд - before & after.
Кроме этого в составе MS SQL есть утилита ISQL или что там у них сейчас...
Ну и прописываешь
DROP CONSTRAINT на before
и
ADD CONSTRAINT на after.
Ну или два батника...
> и хранилище (БД) тоже логичнее генерить из шарповских моделей
-----
Да-да, конечно...
Специфицируй, плс, в шарповой модели... триггер.
А когда специфицируешь - добейся чтобы база его компилировала однократно...
Да, забыл... есть такая ерунда как расширения для МС СКЛ сервера - пишешь сборку, втыкаешь в сервер и юзаешь функциональность.
Недавно Я тут задавал вопросик про пару СКЛ запросов - один из вариантов решения - написать такую сборку... токма там не МС СКЛ, а Постгрее...
Ну и как ты будешь ЭТО генерить из шарповой модели?
Это просто спор о том, на чём лучше писать приложения. DBA говорят, что программисты не нужны - всё на СУБД делать можно, и нужно только прикрутить к СУБД расширения для написания GUI и прочего. Программисты говорят, что DBA не нужны, и БД можно делать на языке программирования, нужно только прикрутить расширения для создания триггеров и прочего.
Беглый поиск показал, что триггеры вкорячиваются через миграции прямо на Transact-SQL:
https://stackoverflow.com/a/56263887/5015385
Я правда не понял, что это за объект или метод Sql с кучей кода внутри - как будто в воздухе висит. Там есть метод RawSql. Но зато поддерживаются параметризованные и интерполированные строки, т.е. можно прямо из Шарпа повставлять в SQL-запрос значения и названия переменных без напечатывания их вручную в голой строке.
Но это явно решение лишь оттого, что изначально Code First не был задуман для 100% замены средств разработки СУБД. С другой стороны, сама СУБД и реляционные БД - костыль для моделей, созданных изначально на ООП.
Если бы всё (в том числе средства хранения данных) изначально для ООП точилось, то не нужны были бы маппинги и прочий костылизм.
Я могу вызвать код Transact-SQL через C# (ну или отправить в СУБД на исполнение), а можно ли в БД через Transact-SQL вызвать код C#?
Ещё можно смешивать коды SQL и C#, а вот наоборот - навряд ли. Вот пример с интерполированной строкой в LINQ
var blogs = context.Blogs .FromSqlInterpolated($"SELECT * FROM dbo.SearchBlogs({searchTerm})") .Where(b => b.Rating > 3) .OrderByDescending(b => b.Rating) .ToList();
Вообще, БД должна только хранить данные. Триггеры и хранимые процедуры - вообще любая логика - это уже "программирование на СУБД", и вынос логики в СУБД. Этого не должно быть. Вся логика в БД должна только обслуживать саму БД и никаких операций с данными не делать. А то борятся-борятся за разделение ответственности по слоям, а потом пихают всё куда попало. Или дублируют логику - типа своя валидация в каждом слое.
И даже в этом идеальном мире это не про то, что пациент пишет.
На триггер возбудился, сразу "логику" увидел. Как дальше жить...
Когда у меня 1 запись на миллион чтений я могу кучу триггеров понаделать. Лишь бы чтение/поиск ускорить. И к "логике приложения" это не будет иметь ни малейшего отношения.
Когда у меня 1 запись на миллион чтений я могу кучу триггеров понаделать. Лишь бы чтение/поиск ускорить. И к "логике приложения" это не будет иметь ни малейшего отношения.
Если ваши триггеры-процедуры обслуживают работу БД, оптимизируют запросы, а не выполняют бизнес-логику проекта, то норм. Но некоторые специалисты по БД пытаются в БД засунуть и бизнес-логику, а потом говорят разработчику приложения "подёргай хранимки", вместо того, чтобы реализовать это в слое бизнес-логики.
так можно дойти и до того, что будем ключи в таблицах запрещать
Ключи нужны для создания реляционных связей. Но по идее, у вас уже есть связи в бизнес-логике. Вы зачем-то дублируете эти связи в БД, но по правилам БД, где не всё можно отобразить на бизнес-слой (и наоборот). А потом через слой работы с БД (ORM или ещё какой паттерн хранилища данных) сглаживаете углы и несовместимости. И вот у вас уже три слоя, с тремя моделями, которые все означают примерно одно и то же, при этом один слой существует вообще лишь для интеграции двух остальных.
Если бы можно было затолкать всю БД в оперативку, то и БД с ORM не понадобилось бы. Тем более, насколько мне известно, СУБД и так в своих оптимизациях держит наиболее часто выполняемые запросы или подзапросы в RAM (или что-то подобное - типа кеша).
То, что создатели баз данных пытаются на своих расширениях SQL целые приложения писать, это как некоторые фронтэндщики пытаются протолкнуть в CSS вычисления и далее продвинуть это, судя по всему, до ещё одного языка программирования. Расширения SQL были сделаны для того, чтобы немного облегчить работу DBA, а не позволить им писать полноценные приложения. Javascript и CSS были придуманы, чтобы немного облегчить жизнь создателям интернет-страничек, а не позволить им писать полноценные приложения. Но всё пошло не по плану...
изначально Code First не был
-----
Он и сейчас до этого не дорос.
По секрету скажу - и не дорастет никогда. Просто это не его область.
Область применения этого инструмента - очень узкая. Очень мелкие базы... по паре-другой тысяч строк на таблицу... прототипирование... ну еще пара мелочей. Для всего остального надо брать ДБА... и менять код под его продукцию.
а можно ли в БД через Transact-SQL вызвать код C#?
-----
Как минимум двумя способами.
Первый - сборкой добавленной к инстансу сервера.
Второй - ловлей эвентов сервера... это как раз к вопросу об тригерах.
изначально Code First не был
-----
Он и сейчас до этого не дорос.
По секрету скажу - и не дорастет никогда. Просто это не его область.
Область применения этого инструмента - очень узкая. Очень мелкие базы... по паре-другой тысяч строк на таблицу... прототипирование... ну еще пара мелочей. Для всего остального надо брать ДБА... и менять код под его продукцию.
Я не знаю СУБД так глубоко. Для повышения производительности таблицы в частности и БД вообще обкуриваются какой-то особо забористой оптимизационной травой, которую не вдохнуть через Code First?