在VS 2010 .net 4.0中使用entity framework时出现'datetime2'错误
得到这个错误:
System.Data.SqlClient.SqlException:将datetime2数据types转换为date时间数据types导致超出范围的值。
我的实体将所有行alignment到DB对象。
我只通过Googlefind了这个错误的一个引用:
谷歌的结果
读完这个之后,我记得我们添加了2个字段,然后更新了VS 2010的实体模型。我不确定他是通过手工编码差异来表示他的意思。 我没有看到任何
我所做的代码是填充实体对象,然后保存。 (我也在代码中填充新的字段)我用DateTime.Now
填充date字段..
代码的重要部分是这样的: ctx.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
数据库是SQL Server 2008。
思考?
其余的错误:
在System.Data.Objects.ObjectContext.SaveChanges(SaveOptions选项)System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache)System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter适配器) SpeciesPost.svc.cs中的SafariAdmin.Site.WebServices.SpeciesPost.SaveOrUpdateSpecies(String sid,String fieldName,String authToken):SpeciesPostSVC_Tester.cs中的SafariAdmin.TestHarness.Tests.Site.WebServices.SpeciesPostSVC_Tester.SaveNewSpecies()中的第58行:line System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()方法System.Data.SqlClient.SqlInternalConnection.OnError(SqlExceptionexception,布尔breakConnection)上的System.Data.SqlClient.SqlConnection.OnError(SqlExceptionexception,布尔breakConnection)在System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader的dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateO bj)System.Data.SqlClient.SqlDataReader.ConsumeMetaData()System.Data.SqlClient.SqlDataReader.get_MetaData()在System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,stringresetOptionsString)在System.Data .SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔returnStream,布尔asynchronous)在System.Data.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔returnStream,string方法,DbAsyncResult结果)在System.Data。 SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔returnStream,string方法)在System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior行为,string方法)在System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior行为)在System.Data.Common.DbCommand.ExecuteReader(CommandBehavior行为)在System.Data.Mapping.Update.Internal.DynamicUpdateComma 在System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter适配器)上的nd.Execute(UpdateTranslator转换器,EntityConnection连接,Dictionary
2 identifierValues, List
1 generatedValues)
entity framework将所有date作为date时间2处理,因此,如果数据库中的date时间是date时间,则这可能是一个问题。 我们在这里也遇到了同样的问题,从我们发现的所有date字段中填充数据types并改变数据types是最常用的解决scheme
如果您使用Code First,则必须将任何可选的DateTime
属性声明为DateTime?
或Nullable<DateTime>
。 取消设置DateTime
对象可能会导致问题。
如果该属性在数据库中可以为空,而在代码中为标准DateTime
时间(不是DateTime?
),则ADO.NET将发送date为0001-01-01(不为NULL
)的插入命令,但最小SQL DateTime值为1753 -01-01,导致错误。 如果代码中的DateTime
属性为空(例如DateTime?
或Nullable<DateTime>
),insert命令将尝试插入NULL
而不是超出范围的date。
使用该SQL脚本将所有列从datetime转换为datetime2
。 它会跳过所有包含“aspnet”的表格,以方便您使用。
DECLARE @SQL AS NVARCHAR(1024) DECLARE @TBL AS NVARCHAR(255) DECLARE @COL AS NVARCHAR(255) DECLARE @NUL AS BIT DECLARE CUR CURSOR FAST_FORWARD FOR SELECT SCHEMA_NAME(t.schema_id)+'.'+t.name, c.name, c.is_nullable FROM sys.tables AS t JOIN sys.columns c ON t.object_id = c.object_id JOIN information_schema.columns i ON i.TABLE_NAME = t.name AND i.COLUMN_NAME = c.name WHERE i.data_type = 'datetime' and t.name not like '%aspnet%' ORDER BY t.name, c.name OPEN CUR FETCH NEXT FROM CUR INTO @TBL, @COL, @NUL WHILE @@FETCH_STATUS = 0 BEGIN SELECT @SQL = 'ALTER TABLE ' + @TBL + ' ALTER COLUMN [' + @COL + '] datetime2' + (CASE WHEN @NUL=1 THEN '' ELSE ' NOT' END) + ' NULL;' EXEC sp_executesql @SQL FETCH NEXT FROM CUR INTO @TBL, @COL, @NUL END CLOSE CUR; DEALLOCATE CUR;
这个对我有用!
另一种可能的解决scheme是将字段的sql列types设置为datetime2。 这可以使用fluentapi完成。
Property(x => x.TheDateTimeField) .HasColumnType("datetime2");
注意:这是SQL Server 2008向上的解决scheme,因为datetime2不适用于sql server 2005或更低版本。
我有同样的问题,并通过将[Column(TypeName = "datetime2")]
属性相关的属性解决它,如下面的示例:
[Column(TypeName = "datetime2")] public DateTime? PropertyName { get; set; }
我知道这是一个老问题,但是当我在这里search时,别人也可以做同样的事情;-)对于那些从DateTime更改为DateTime2不是一个选项(对于SQL2005用户),我认为在大多数情况下更合理的填充字段留空像类似(DateTime)System.Data.SqlTypes.SqlDateTime.MinValue
而不是与DateTime.now,因为它更容易将其识别为“伪空值”(如果需要将其转换为父对象的部分类中的真实空值)
首先使用实体框架代码,如下所示:
public Nullable<System.DateTime> LastLogin { get; set; }
您的实体中是否有ModifiedTime属性,仅在数据库端更新? 如果是这样,您必须使用DatabaseGeneratedOption.Computed(对于EF CodeFirst)。 也访问这个https://stackoverflow.com/a/9508312/1317263
谢谢。
我们有同样的问题。 这与mssql版本有关。 我们使用这种方法在我们的所有版本上都能正常工作。
用xml编辑器打开你的edmx文件在文件的顶部find这一行
<Schema Namespace="XXXXX.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008"
replace2008年到2005年保存你的文件,重新编译项目。
希望能够帮助未来的其他人。
我只用dbfirst方法来尝试这个解决scheme。
无论date时间适合什么都适合datetime2数据types,反之亦然,事实并非如此,你可以在datetime2数据types中保留1500年1月的date,但datetime只能返回到1753年,datetime2列可以返回所有到年份的方式1.我会检查你传递的最短date是什么,如果你的表有datetime2或date时间数据types列
试图解决这个问题几天后,我用DateTime?
作为我的模型中的entity frameworkCode-First而不是DateTime
的数据types。
确保插入/更新时,DB(date时间)中的所有非空字段都没有被使用。 我有相同的错误,并将值插入到这些date时间字段的问题已得到解决。如果非空date时间字段未分配适当的值,则会发生此问题。
我在我的ASP.Net MVC应用程序中有同样的问题。
我的应用程序中有两个具有DateTime属性的模型类。
经过调查,我注意到一个模型的DateTime属性是可以为空的,即使它的出生可选属性的date
另一个模型有DateTime属性和必需的数据注释(保存此模型时发生错误)
我的应用程序是第一代码,所以我通过将数据types设置为DateTime2来解决问题
[Column(TypeName="datetime2")]
然后我在包pipe理器控制台上运行迁移。
简单。 在您的代码中,将DateTime的types设置为DateTime ?. 所以你可以在数据库中使用可空的DateTimetypes。
这跟从stepanZ答案…我得到这个错误时,使用Entity Framework Code First
与AutoMapper
。
设置AutoMapping
我们createddt
自动创build, updateddt
,创build和更新的字段,这些字段在我们的public override int SaveChanges()
函数中自动设置。 当你这样做的时候,你需要确保你设置的这些字段被AutoMapper
忽略,否则当数据库没有被View
提供时,数据库会被更新为null
。
我的问题是,我已经把源和目标放在错误的方式,因此设置ViewModel
,而不是设置Model
时,试图忽略字段。
当我收到这个错误(注意:第二行的cfg.CreateMap<Source, Destination>()
将Model
映射到ViewModel
并设置Ignore()
)
cfg.CreateMap<EventViewModel, Event>(); cfg.CreateMap<Event, EventViewModel>() .ForMember(dest => dest.CreatedBy, opt => opt.Ignore()) .ForMember(dest => dest.CreatedDt, opt => opt.Ignore()) .ForMember(dest => dest.UpdatedBy, opt => opt.Ignore()) .ForMember(dest => dest.UpdatedDt, opt => opt.Ignore());
对于从ViewModel
到Model
的映射,源和目标应该被忽略(注意:下面的代码在Ignore()
放置在ViewModel
到Model
的映射的位置是正确的)
cfg.CreateMap<Event, EventViewModel>(); cfg.CreateMap<EventViewModel, Event>() .ForMember(dest => dest.CreatedBy, opt => opt.Ignore()) .ForMember(dest => dest.CreatedDt, opt => opt.Ignore()) .ForMember(dest => dest.UpdatedBy, opt => opt.Ignore()) .ForMember(dest => dest.UpdatedDt, opt => opt.Ignore());
两种解决scheme
-
在你的类声明属性像下面,并build立一个更新数据库:
public DateTime? MyDate {get; set;}
-
或者在填充数据库的Seed方法中为该属性设置date,不需要update-database:
context.MyClass.AddOrUpdate(y => y.MyName,new MyClass { MyName = "Random", MyDate= DateTime.Now })