entity-framework – 为什么EF5代码在将可空日期时间插入数据库
我将Cart对象保存到具有可为空的日期时间的数据库.这是我得到的错误:
有很多stackoverflow帖子记录了此问题的修复程序.但是,当代码首先创建数据库时,它将创建该字段作为DateTime(允许空值).但由于某种原因,代码首先尝试使用DateTime2字段插入. 我想知道为什么EF以单向方式创建字段,但是为同一字段使用不同类型插入. 这是域对象: 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 */ } } 该模型: 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 */ } } 那么OpeningDateUtc和ClosingDateUtc的类型都是DateTime?. 这是EF代码首先生成数据库的方式: OpeningDateUtc和ClosingDateUtc创建为可为空的DateTime字段. 那么为什么当我使用IDBContext.SaveChanges()进行保存时,为查询生成的SQL是: 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 有趣的部分是@ 4 datetime2(7),@ 5 datetime2(7). 我知道我可以通过在购物车地图中添加.HasColumnType(“datetime2”)来解决这个问题,但它没有回答为什么EF5(可能还有旧版本)将它们设置为可以为空的日期时间. 解决方法.NET中的DateTime类型与SQL Server中的datetime2具有相同的范围和精度.当EF在SQL Server中插入或更新datetime或datetime2列时,它会将model属性转换为可以在.NET中保存整个DateTime范围的类型,即datetime2.如果DateTime属性不在SQL Server中的datetime范围内,则转换为datetime将失败.顺便说一下,导致异常的问题不是两个可空的OpeningDateUtc和ClosingDateUtc列,而是SQL片段中的CreatedOnUtc值’0001-01-01 00:00:00′,即CreatedOnUtc显然未初始化在您的模型实体中. SQL Server中可以存储的日期时间最早的日期是1750年,因此0001年不适合该类型(但它适合datetime2). 因此,解决方案是将CreatedOnUtc设置为有效的日期时间值,或者 – 如您所知 – 在映射中将类型定义为datetime2. 但我同意,如果EF默认将DateTime属性映射到datetime2,则会产生更少的混淆. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |