До сих пор я читал документы, учебные пособия, подготовленные Google, и другие вопросы SO, но, похоже, я что-то пропустил, и у меня это не получается (для работы).
Я пытаюсь реализовать действительно крошечную базу данных PostgreSQL для веб-API .NET Core 2.1 (микросервиса). Я привык к первому подходу к базе данных, но для этой услуги я решил сначала попробовать код.
Я также решил использовать свободный API ModelBuilder, чтобы не допустить в классах атрибутов и определить большую часть структуры в методе DbContext.OnModelCreating. Энди, возможно, однажды найдет решение, как очистить DbContext от конкретных элементов Postgres и переместить их в миграции ...
Моя проблема в том, что требования определяют множество значений по умолчанию, и я не могу заставить их работать так, как они должны себя вести.
Например, у меня есть таблица Entity1, в которой всего 3 столбца:
Идея, лежащая в основе значения по умолчанию для метки времени, состоит в том, чтобы база данных была единственным экземпляром, создающим метки времени и использующим значения по умолчанию 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?
Для будущих читателей я смог заставить это работать для НОВЫХ строк: builder.Property (t => t.MyColumnCreateDate) .HasDefaultValueSql ("CURRENT_TIMESTAMP" ); Не требовалось ни ValueGeneratedOnAddOrUpdate, ни HasColumnType (по умолчанию он был равен «отметке времени без часового пояса») («PostgreSQL 12.1, скомпилирован Visual C++ build 1914, 64-разрядная версия») Я думаю, вам придется использовать триггер при ОБНОВЛЕНИИ. Это похоже на ответ @GetoX, но не с использованием проприетарного NOW ()





Как в документации EF Core упоминается, HasDefaultValue() и HasDefaultValueSql() определяют только значение, которое устанавливается при вставке новой строки. Установка для столбца значения NULL - это совершенно другое дело (в конце концов, NULL является допустимым значением для этих столбцов). Возможно, вы ищете вычисляемые столбцы, это другая функция.
К сожалению, как и в документах Npgsql упоминается, в настоящее время PostgreSQL не поддерживает вычисляемые столбцы. Это можно настроить с помощью Триггеры базы данных PostgreSQL, но это не управляется EF Core, поэтому вам придется использовать SQL в своих миграциях, чтобы настроить это.
Обратите внимание, что поддержка (хранимых) вычисляемых столбцов была добавлена в PostgreSQL 12, и они также поддерживаются поставщиком Npgsql EF Core (посмотреть документацию).
Решение для CreateDate в PostgreSQL:
builder.Property(e => e.CreationDate)
.HasColumnType("timestamp without time zone")
.HasDefaultValueSql("NOW()")
.ValueGeneratedOnAdd();
К сожалению, для события обновления нет решения.
Для будущих читателей, если вы хотите использовать непатентованную функцию (СЕЙЧАС), вы можете сделать это: builder.Property (t => t.MyColumnCreateDate) .HasDefaultValueSql ("CURRENT_TIMESTAMP" );
Установка значения null не должна вызывать значение по умолчанию. Как с помощью этого подхода кто-то на самом деле поместил бы null в базу данных? Я не ненавижу, просто указываю на это. Если бы это сработало так, как вы предполагаете, будет еще один «лагерь», говорящий: «Если я установлю для него значение null, почему значение null не будет использоваться?» ............ но проголосуйте за сам вопрос .