Значение по умолчанию, не соблюдаемое при вставке ядра Entity Framework

#entity-framework-core

#entity-framework-core

Вопрос:

Моя таблица SQL Server 2017 создается в Transact-SQL следующим образом:

 SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[JobTag]
(
    [JobId] [int] NOT NULL,
    [Name] [nvarchar](64) NOT NULL,
    [Created] [datetime] NOT NULL,
    [Value] [nvarchar](max) NULL,
    [Comment] [nvarchar](2048) NULL,

    CONSTRAINT [PK_JobTag_1] 
       PRIMARY KEY CLUSTERED ([JobId] ASC, [Name] ASC)
                   WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                         IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

ALTER TABLE [dbo].[JobTag] 
    ADD CONSTRAINT [DF_JobTag_Created] DEFAULT (GETDATE()) FOR [Created]
GO

ALTER TABLE [dbo].[JobTag]  WITH CHECK 
    ADD CONSTRAINT [FK_JobTag_job] 
        FOREIGN KEY([JobId]) REFERENCES [dbo].[job] ([JobID])
GO

ALTER TABLE [dbo].[JobTag] CHECK CONSTRAINT [FK_JobTag_job]
GO
  

Для модели я включаю

  public System.DateTime Created { get; set; }
  

В .Net Core, когда я пытаюсь добавить запись с помощью

    var newTag = new JobTag { JobId = job.JobID, Name = "myName", Value = myValueString};
   connect.JobTags.Add(newTag)
   connect.SaveChanges()
  

Я получаю сообщение об ошибке

Майкрософт.EntityFrameworkCore.Исключение DbUpdateException:
Произошла ошибка при обновлении записей. Подробности см. во внутреннем исключении.

System.Data.SqlClient.SQLException: преобразование типа данных datetime2 в тип данных datetime привело к значению, выходящему за пределы диапазона

Я не получаю сообщение об ошибке, если я инициализирую Created свойство с помощью DateTime.Now .

Если я удалю свойство из модели, то дата-время SQL Server используется правильно.

Зачем мне нужно инициализировать свойство, когда оно имеет значение по умолчанию?

Комментарии:

1. Используйте конфигурацию Fluent API, и она сгенерирует соответствующее ограничение по умолчанию для автоматической генерации даты и времени

2. Одним из простых решений является использование datetime2 вместо datetime для Created столбца

3. @TanvirArjel будет ли при этом использоваться datetime из базы данных? Код c # выполняется на другом компьютере.

4. При вставке в базу данных будет сгенерирован соответствующий столбец datetime для Created . Вам не нужно назначать его вручную в коде c #.

5. Да, это: modelBuilder.Entity<Blog>().Property(b => b.Created).HasDefaultValueSql("getdate()");

Ответ №1:

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

В вашей модели это должно быть DateTime.Теперь о дате по умолчанию.

Если вы действительно хотели разрешить нули

Ввод даты и времени? для типа столбца в модели может устранить проблему. Это позволит принять значение null с точки зрения приложения, что, вероятно, происходит до создания записи в базе данных.

 public DateTime? Created { get;set;}
  

Если вы не хотите разрешать значения null и хотите гибко не указывать значение при создании новой записи из приложения

установите для него значение по умолчанию в вашей модели:

 public DateTime Created { get;set;}=DateTime.Now
  

Проблема заключается

В вашей базе данных вы говорите, что это обязательно:

 [Created] [datetime] NOT NULL,
  

Но в приложении вы его не устанавливаете.

 var newTag = new JobTag { JobId = job.JobID,     Name = "myName", Value = myValueString};  
connect.JobTags.Add(newTag)
connect.SaveChanges()
  

Проблема двоякая, поскольку при настройке:

 public DateTime Created { get;set;}
  

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

Требование должно совпадать в обоих местах.

Комментарии:

1. Конечно, создано общедоступное DateTime { get; set;}=DateTime. Теперь в модели не имеет того же эффекта, что при использовании getdate() в fluent api?

2. В итоге мне нужно либо объявить свойства fluent api, либо не указывать дату-время в модели.