Вероятно, это вычисляемый столбец в SQL Server, поэтому в вашем коде нет нигде, где он фактически устанавливается - это делается на сервере, когда строка добавляется изначально.EF не будет включать вычисленные столбцы в запросы на обновление и будет читать столбцы после запроса на обновление, чтобы загрузить потенциально обновленное значение из хранилища данных.
Обновление после обсуждения:
Вот минимальное решение, в котором значение по умолчанию корректно обновляется по требованию.
Сначала создайте новую таблицу на SQL Server:
CREATE TABLE [dbo].[DateDefaultTest](
[AnId] [int] IDENTITY(1,1) NOT NULL,
[CreatedOn] [datetime2](7) NOT NULL,
[SomeField] [nvarchar](50) NULL,
CONSTRAINT [PK_DateDefaultTest] PRIMARY KEY CLUSTERED
(
[AnId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[DateDefaultTest] ADD CONSTRAINT [DF_DateDefaultTest_CreatedOn] DEFAULT (getutcdate()) FOR [CreatedOn]
GO
Поле идентификатора имеет видавтоинкрементный первичный ключ, строковое поле и интересующее нас поле CreatedOn
. Мы добавили ограничение DEFAULT, чтобы установить для него текущую дату и время UTC.
Далее создайте консольприложение, добавьте EF через NuGet и настройте DbContext как обычно.Я назвал свой контекст DefaultTestEntities
.
Сгенерированный код для сущности выглядит следующим образом:
public partial class DateDefaultTest
{
public int AnId { get; set; }
public System.DateTime CreatedOn { get; set; }
public string SomeField { get; set; }
}
На странице свойств диаграммы EF для поля CreatedOn
ничего не имеетбыл изменен.
Используйте следующий код для добавления пары строк:
using (var db = new DefaultTestEntities())
{
db.DateDefaultTests.Add(new DateDefaultTest
{
SomeField = "Bananas"
});
db.DateDefaultTests.Add(new DateDefaultTest
{
SomeField = "Apples",
});
db.SaveChanges();
}
Они должны появиться в таблице с текущими датой и временем, установленными, как и ожидалось.
Как вы обнаружили, если вы попытаетесь установить CreatedOn
вручную при вставке новой строки, это не будет работать из-за ограничений SQL Server.Например:
db.DateDefaultTests.Add(new DateDefaultTest
{
SomeField = "Pears",
CreatedOn = DateTime.UtcNow.AddHours(1)
});
приведет к бессмысленной дате '0001-01-01'.
Вам придется обновить существующую строку, если вы хотите установить CreatedOn
в явном виде.Для этого:
db.DateDefaultTests
.Where(x => x.SomeField == "Bananas")
.First()
.CreatedOn = DateTime.UtcNow.AddDays(-1);
db.SaveChanges();
Если это не относится к вашей ситуации, я бы порекомендовал вам:
- Проверьте свой столбец в SQL Server, чтобы убедиться, что значение не соответствуетcomputed
- Восстановить модель
- Подтвердить, что в вашем коде нет переопределений EF, которые могут повлиять на значение при сохранении сущности
Извинения за комментарийгде я сказал EF не будет обновлять столбцы по умолчанию.Это неверно и относится только к начальной вставке.
Обновление - необходимые настройки:

