Entity framework 为什么EF5代码在将可为空的datetime插入数据库时首先使用datetime2?
我正在将Cart对象保存到datetime为空的数据库中。这是我得到的错误: 将datetime2数据类型转换为datetime数据类型 导致值超出范围 有相当多的stackoverflow帖子记录了对这个问题的修复。但是,当代码第一次创建数据库时,它会将字段创建为日期时间(允许空值)。但出于某种原因,代码首先尝试使用DateTime2字段进行插入 我想知道为什么EF以一种方式创建字段,但对同一字段使用不同类型的插入 这是域对象:Entity framework 为什么EF5代码在将可为空的datetime插入数据库时首先使用datetime2?,entity-framework,datetime,ef-code-first,datetime2,Entity Framework,Datetime,Ef Code First,Datetime2,我正在将Cart对象保存到datetime为空的数据库中。这是我得到的错误: 将datetime2数据类型转换为datetime数据类型 导致值超出范围 有相当多的stackoverflow帖子记录了对这个问题的修复。但是,当代码第一次创建数据库时,它会将字段创建为日期时间(允许空值)。但出于某种原因,代码首先尝试使用DateTime2字段进行插入 我想知道为什么EF以一种方式创建字段,但对同一字段使用不同类型的插入 这是域对象: using System; using System.Colle
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 */
}
}
有趣的部分是@4datetime2(7),@5datetime2(7)
我知道我可以通过在购物车映射中添加一个
.HasColumnType(“datetime2”)
来解决这个问题,但它不能回答为什么EF5(可能还有更旧的版本)将它们设置为可为空的datetime。在.NET中的datetime
类型与SQL Server中的datetime2
具有相同的范围和精度。当EF在SQL Server中插入或更新datetime
或datetime2
列时,它会将模型属性转换为可在.NET中保存整个datetime
范围的类型,即datetime2
。如果datetime
属性不在SQL Server中的datetime
范围内,则转换为datetime
将失败
顺便说一句,导致异常的问题不是两个可为空的OpeningDateUtc
和ClosingDateUtc
列,而是CreatedOnUtc
值,即SQL代码段中的'0001-01-01 00:00:00'
,即CreatedOnUtc
显然没有在模型实体中初始化。SQL Server中datetime
可以存储的最早日期是1750年,因此0001年不适合该类型(但适合datetime 2
)
因此,解决方案是将CreatedOnUtc
设置为有效的datetime
值,或者如您所知,在映射中将类型定义为datetime2
但我同意,如果EF将默认的
DateTime
属性映射到datetime2
,那么就不会有太多的混淆。EF团队实际上在一次设计会议上讨论了这个特定项目。决定是保持当前行为不变。以下是可以为您提供更多上下文信息的示例。谢谢,我有一个解决方案。
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 */
}
}
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