Entity Framework Core code первые значения по умолчанию для PostgreSQL

До сих пор я читал документы, учебные пособия, подготовленные Google, и другие вопросы SO, но, похоже, я что-то пропустил, и у меня это не получается (для работы).

Я пытаюсь реализовать действительно крошечную базу данных PostgreSQL для веб-API .NET Core 2.1 (микросервиса). Я привык к первому подходу к базе данных, но для этой услуги я решил сначала попробовать код.

Я также решил использовать свободный API ModelBuilder, чтобы не допустить в классах атрибутов и определить большую часть структуры в методе DbContext.OnModelCreating. Энди, возможно, однажды найдет решение, как очистить DbContext от конкретных элементов Postgres и переместить их в миграции ...

Моя проблема в том, что требования определяют множество значений по умолчанию, и я не могу заставить их работать так, как они должны себя вести.

Например, у меня есть таблица Entity1, в которой всего 3 столбца:

  • int Id (автоматически увеличивающийся идентификатор)
  • булево? IsEnabled (который должен получить значение по умолчанию true)
  • DateTime? LastStatusChange (отметка времени без часового пояса, которая должна быть установлена ​​при создании или обновлении до значения по умолчанию CURRENT_TIMESTAMP)

Идея, лежащая в основе значения по умолчанию для метки времени, состоит в том, чтобы база данных была единственным экземпляром, создающим метки времени и использующим значения по умолчанию db в качестве конфигурации для всех запущенных экземпляров. Например. когда требования меняются на «значение по умолчанию теперь должно быть ложным», мы просто изменяем значения по умолчанию db в существующих базах данных и обновляем миграцию для новых частей.

В настоящее время мой код modelBuilder:

  modelBuilder.Entity<Entity1>(entity =>
  {
    entity.HasKey(e => e.Id);

    entity.Property(e => e.Id)
      .ValueGeneratedOnAdd();

    entity.Property(e => e.IsEnabled)
      .HasDefaultValue(true)
      .ValueGeneratedOnAddOrUpdate();

    entity.Property(e => e.LastStatusChange)
      .HasColumnType("timestamp without time zone")
      .HasDefaultValueSql("CURRENT_TIMESTAMP")
      .ValueGeneratedOnAddOrUpdate();
  });

Что работает для новых созданных ценностей.

При переключении или сбросе полей, которые я использую

entity.LastStatusChange = null;

и или

entity.IsEnabled = null;

Я предположил, что установка для них значения null вызовет создание значения по умолчанию, но это не влияет на поле LastStatusChange (значение остается прежним) и устанавливает IsEnabled в значение null.

В любом случае, чтобы получить значения по умолчанию db при обновлении через ядро ​​entity framework?

Установка значения null не должна вызывать значение по умолчанию. Как с помощью этого подхода кто-то на самом деле поместил бы null в базу данных? Я не ненавижу, просто указываю на это. Если бы это сработало так, как вы предполагаете, будет еще один «лагерь», говорящий: «Если я установлю для него значение null, почему значение null не будет использоваться?» ............ но проголосуйте за сам вопрос .

granadaCoder 07.01.2020 16:08

Для будущих читателей я смог заставить это работать для НОВЫХ строк: builder.Property (t => t.MyColumnCreateDate) .HasDefaultValueSql ("CURRENT_TIMESTAMP" ‌); Не требовалось ни ValueGeneratedOnAddOrUpdate, ни HasColumnType (по умолчанию он был равен «отметке времени без часового пояса») («PostgreSQL 12.1, скомпилирован Visual C++ build 1914, 64-разрядная версия») Я думаю, вам придется использовать триггер при ОБНОВЛЕНИИ. Это похоже на ответ @GetoX, но не с использованием проприетарного NOW ()

granadaCoder 07.01.2020 18:06
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
6
2
10 767
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Как в документации EF Core упоминается, HasDefaultValue() и HasDefaultValueSql() определяют только значение, которое устанавливается при вставке новой строки. Установка для столбца значения NULL - это совершенно другое дело (в конце концов, NULL является допустимым значением для этих столбцов). Возможно, вы ищете вычисляемые столбцы, это другая функция.

К сожалению, как и в документах Npgsql упоминается, в настоящее время PostgreSQL не поддерживает вычисляемые столбцы. Это можно настроить с помощью Триггеры базы данных PostgreSQL, но это не управляется EF Core, поэтому вам придется использовать SQL в своих миграциях, чтобы настроить это.

Обратите внимание, что поддержка (хранимых) вычисляемых столбцов была добавлена ​​в PostgreSQL 12, и они также поддерживаются поставщиком Npgsql EF Core (посмотреть документацию).

Shay Rojansky 10.04.2020 13:56

Решение для CreateDate в PostgreSQL:

builder.Property(e => e.CreationDate)
  .HasColumnType("timestamp without time zone")
  .HasDefaultValueSql("NOW()")
  .ValueGeneratedOnAdd();

К сожалению, для события обновления нет решения.

Для будущих читателей, если вы хотите использовать непатентованную функцию (СЕЙЧАС), вы можете сделать это: builder.Property (t => t.MyColumnCreateDate) .HasDefaultValueSql ("CURRENT_TIMESTAMP" ‌);

granadaCoder 07.01.2020 18:06

Другие вопросы по теме