Entity framework genera valores para las columnas NOT NULL que tienen el valor predeterminado definido en db

Hola tengo un cliente de mesa. Una de las columnas en la tabla es DateCreated . Esta columna NOT NULL es NOT NULL pero los valores predeterminados se definen para esta columna en db.

Cuando agrego nuevo Customer usando EF4 desde mi código.

 var customer = new Customer(); customer.CustomerName = "Hello"; customer.Email = "hello@ello.com"; // Watch out commented out. //customer.DateCreated = DateTime.Now; context.AddToCustomers(customer); context.SaveChanges(); 

El código anterior genera la siguiente consulta.

 exec sp_executesql N'insert [dbo].[Customers]([CustomerName], [Email], [Phone], [DateCreated], [DateUpdated]) values (@0, @1, null, @2, null) select [CustomerId] from [dbo].[Customers] where @@ROWCOUNT > 0 and [CustomerId] = scope_identity() ',N'@0 varchar(100),@1 varchar(100),@2 datetime2(7) ',@0='Hello',@1='hello@ello.com',@2='0001-01-01 00:00:00' 

Y arroja el siguiente error.

 The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value. The statement has been terminated. 

¿Puede decirme cómo las columnas NOT NULL que tienen valores predeterminados en el nivel de db no deberían tener valores generados por EF?

DB:

 DateCreated DATETIME NOT NULL 

DateCreated Propiedades en EF:

  • Nullable: Falso
  • Getter / Setter: público
  • Tipo: DateTime
  • Valor por defecto: Ninguno

Gracias.

Desde mi conocimiento de EF (que es mínimo), no toma el valor predeterminado del esquema. El hecho de que esté insertando la fila y la columna está marcado como NO NULO, significa que EF piensa que debería estar insertando un valor para esa columna que tenga el valor de DateTime.MinValue.

Es posible que deba forzar sus propios valores en el constructor de entidades o crear algunos métodos de fábrica.

¿Hay algo en las páginas de propiedades del diseñador de tablas en EF que le permita especificar un valor predeterminado?

NOT NULL columna NOT NULL significa que la propiedad no es anulable y debe tener un valor en su entidad. Si no especifica un valor en el tipo de valor como DateTime el valor predeterminado se mantendrá. El valor predeterminado para DateTime es DateTime.MinValue .

Como sé, EF no admite el escenario en el que puede usar la columna NOT NULL y no enviar ningún valor desde su aplicación. La única excepción es cuando establece StoreGeneratedPattern para la propiedad en Identity o Computed pero en tal caso no podrá establecer el valor en la aplicación.

Para que pueda establecer valor en la aplicación o en la base de datos. No en ambos.

Tienes que decirle al ORM que la propiedad es generada por la base de datos. Para el ejemplo en la Clase de clientes en el ejemplo anterior, el siguiente código debería funcionar.

 public class Customer{ [Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]//The database generates a value when a row is inserted. public int CustomerId { get; set; } public string CustomerName { get; set; } public string Email { get; set; } public string Phone { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] //The database generates a value when a row is inserted or updated. public DateTime DateCreated { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.IComputed)]//The database generates a value when a row is inserted or updated. public DateTime DateUpdated { get; set; } } 

No olvides añadir el

 [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] 

a la clave principal , por una razón que no conozco, cuando usa la anotación de DatabaseGeneratedAttribute al menos una vez en la Clase de modelo, debe especificar el método de opción generado. Cuando los uso, tengo un error porque el ORM intentaba insertar la clave en la statement de consulta en lugar de dejar que la base de datos los generara.

Hay tres opciones de base de datos generadas

  • Calculado : la base de datos genera un valor cuando se inserta o actualiza una fila.
  • Identidad : la base de datos genera un valor cuando se inserta una fila.
  • Ninguno : La base de datos no genera valores.

Puede encontrar la documentación aquí.

¿Posiblemente la columna DateCreated sea smalldatetime y deba ser un tipo datetime ? Intente cambiar el tipo de columna en Visual Studio o Management Studio.

  1. Establecer el DateCreated permitir nulo
  2. Añadir un disparador para INSERT

    CREAR TRIGGER [dbo]. [ItemCreated]

    ON [dbo]. [MyTable]

    Después de insertar

    COMO

    ACTUALIZACIÓN [dbo]. [MyTable]

    SET [DateCreated] = GETDATE ()

    WHERE [ID] IN (SELECT DISTINCT [ID] DE [Insertada]) y [DateCreated] es NULL