Sto salvando un oggetto Cart nel database che ha un datetime nullable. Questo è l'errore ottengo:Perché il codice EF5 utilizza prima datetime2 quando si inserisce un datetime nullable nel database?
La conversione di un tipo di dati datetime2 un tipo di dati datetime determinato un valore out-of-range.
Ci sono alcuni post Stackoverflow che documentano le correzioni a questo problema. Tuttavia, quando il codice crea per la prima volta il database, creerà il campo come DateTime (consentire i valori null). Ma per qualche ragione, il codice tenta prima di inserirlo usando un campo DateTime2.
Mi chiedo perché EF crea il campo in un modo, ma inserisce un diverso tipo per lo stesso campo.
Questo è l'oggetto di dominio:
using System;
using System.Collections.Generic;
namespace Core.Domain.Cart
{
public partial class Cart : BaseEntity, ILocalizedEntity
{
private ICollection<Catalog> _catalogs;
/// <summary>
/// Gets or sets the name
/// </summary>
public virtual string Name { get; set; }
/// <summary>
/// Gets or sets the zone identifier
/// </summary>
public virtual int ZoneId { get; set; }
/// <summary>
/// Gets or sets the brand identifier
/// </summary>
public virtual int BrandId { get; set; }
/// <summary>
/// Gets or sets the customer type identifier
/// </summary>
public virtual int CustomerTypeId { get; set; }
/// <summary>
/// Gets or sets the date and time of the opening of a cart
/// </summary>
public virtual DateTime? OpeningDateUtc { get; set; }
/// <summary>
/// Gets or sets the date and time of the closing of a cart
/// </summary>
public virtual DateTime? ClosingDateUtc { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the entity is online or not
/// </summary>
public virtual bool IsOnline { get; set; }
/* Truncated for relevance */
}
}
Il modello:
using FluentValidation.Attributes;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web.Mvc;
using Telerik.Web.Mvc;
namespace Admin.Models.Cart
{
[Validator(typeof(CartValidator))]
public partial class CartModel : BaseNopEntityModel, ILocalizedModel<CartLocalizedModel>
{
public CartModel()
{
Locales = new List<CartLocalizedModel>();
Catalogs = new List<CatalogModel>();
UnassociatedCatalogs = new List<CatalogModel>();
}
[NopResourceDisplayName("Admin.Carts.Fields.Name")]
[AllowHtml]
public string Name { get; set; }
//Zone dropdown
[NopResourceDisplayName("Admin.Carts.Fields.ZoneList")]
public SelectList ZoneList { get; set; } //The dropdown with zones
public int ZoneId { get; set; } //The selected value of the dropdown once the form is submitted
public string ZoneName { get; set; } //The name of the zone to display in data-grid List view.
//Brand dropdown
[NopResourceDisplayName("Admin.Carts.Fields.BrandList")]
public SelectList BrandList { get; set; } //The dropdown with brands
public int BrandId { get; set; } //The selected value of the dropdown once the form is submitted
public string BrandName { get; set; } //The name of the brand to display in the data-grid List view.
//Customer type dropdown
[NopResourceDisplayName("Admin.Carts.Fields.CustomerTypeList")]
public SelectList CustomerTypeList { get; set; }//The dropdown with CustomerType
public int CustomerTypeId { get; set; } //The selected value of the dropdown once the form is submitted
public string CustomerTypeName { get; set; } //The name of the CustomerType to display in the data-grid List view.
[NopResourceDisplayName("Admin.Carts.Fields.OpeningDateUtc")]
[UIHint("DateNullable")]
public DateTime? OpeningDateUtc { get; set; }
[NopResourceDisplayName("Admin.Carts.Fields.ClosingDateUtc")]
[UIHint("DateNullable")]
public DateTime? ClosingDateUtc { get; set; }
[NopResourceDisplayName("Admin.Carts.Fields.IsOnline")]
public bool IsOnline { get; set; }
/* Truncated for relevance */
}
}
Così sia il OpeningDateUtc
e ClosingDateUtc
sono del tipo DateTime ?.
In questo modo il database viene generato dal codice EF prima:
Il OpeningDateUtc
e ClosingDateUtc
sono creati come un campo DateTime nullable.
Allora perché è quando salvo utilizzando il IDBContext.SaveChanges()
, l'SQL generato per la query è:
exec sp_executesql N'update [dbo].[Cart]
set [Name] = @0, [ZoneId] = @1, [BrandId] = @2, [CustomerTypeId] = @3, [OpeningDateUtc] = @4, [ClosingDateUtc] = @5, [IsOnline] = @6, [IsReadonly] = @7, [IsPreviewMode] = @8, [CreatedOnUtc] = @9
where ([Id] = @10)
',N'@0 nvarchar(100),@1 int,@2 int,@3 int,@4 datetime2(7),@5 datetime2(7),@6 bit,@7 bit,@8 bit,@9 datetime2(7),@10 int',@0=N'Cart1',@1=7,@2=4,@3=5,@4='2013-01-09 00:00:00',@5='2013-01-18 00:00:00',@6=0,@7=0,@8=1,@9='0001-01-01 00:00:00',@10=1
La parte interessante è @4 datetime2(7),@5 datetime2(7)
.
Capisco che potrei risolvere questo problema aggiungendo un .HasColumnType("datetime2")
alla mappa del carrello, ma non risponde perché EF5 (e probabilmente vecchie versioni) li imposta su datetime nullable.
Grazie, ho una soluzione. –