[英]'datetime2' error when using entity framework in VS 2010 .net 4.0
得到此错误:
System.Data.SqlClient.SqlException:将datetime2数据类型转换为日期时间数据类型会导致超出范围的值。
我的实体对象全部排列到DB对象。
我通过Google发现只有一个引用此错误:
阅读本文之后,我记得我们确实添加了2个字段,然后从VS 2010更新了实体模型。我不确定他的意思是“手工编码”差异。 我没有看到任何。
我在代码中所做的就是填充实体对象,然后保存。 (我还在代码中填充新字段)我用DateTime.Now
填充了日期字段。
代码的重要部分是: ctx.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
该数据库是SQL Server 2008。
思考?
其余的错误:
在System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter适配器)的System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager entityCache)处于System.Data.Objects.ObjectContext.SaveChanges(SaveOptions选项)at at 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 33 - System.Data.SqlClient上的System.Data.SqlClient.SqlConnection.OnError(SqlException异常,布尔breakConnection)中的SystemException.SqlClient.SupInternalConnection.OnError(SqlException异常,布尔breakConnection),System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()在System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateO bj)System.Data上的System.Data.SqlClient.SqlDataReader.get_MetaData()处的System.Data.SqlClient.SqlDataReader.ConsumeMetaData()处于System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,String resetOptionsString) System.Data上的System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String方法,DbAsyncResult结果)中的.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,Boolean async)。 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior behavior)at的System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior,String method)中的SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String方法) System.Data.Mapping.Update.Internal.DynamicUpdateComma中的System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior) System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter adapter)中的nd.Execute(UpdateTranslator转换器,EntityConnection连接,Dictionary
2 identifierValues, List
1 generatedValues)
实体框架将所有日期作为Datetime2处理,因此,如果数据库中的字段是Datetime,则可能会出现问题。 我们在这里遇到了同样的问题,从我们发现的,填充所有日期字段和更改数据类型,是最常见的解决方案
如果您使用的是Code First,则必须将任何可选的DateTime
属性声明为DateTime?
或Nullable<DateTime>
。 取消设置DateTime
对象可能会导致问题。
如果属性在数据库中可以为空并且代码中的标准DateTime
(不是DateTime?
),则ADO.NET将发送日期为0001-01-01(非NULL
)的插入命令,但最小SQL DateTime值为1753 -01-01,导致错误。 如果代码中的DateTime
属性可以为空(例如DateTime?
或Nullable<DateTime>
),则insert命令将尝试插入NULL
而不是超出范围的日期。
使用该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;
这个对我有用!
另一种可能的解决方案是将字段的sql列类型设置为datetime2。 这可以使用fluentapi完成。
Property(x => x.TheDateTimeField)
.HasColumnType("datetime2");
注意:这是sql server 2008向上的解决方案,因为datetime2不适用于sql server 2005或更低版本。
我有同样的问题并通过将[Column(TypeName = "datetime2")]
属性放到相关属性来解决它,如下面的示例:
[Column(TypeName = "datetime2")]
public DateTime? PropertyName { get; set; }
我知道这是一个老问题,但是当我在这里搜索时,其他人也可以这样做;-)对于那些从DateTime更改为DateTime2的人不是一个选项(对于SQL2005用户),我认为在大多数情况下是使用类似(DateTime)System.Data.SqlTypes.SqlDateTime.MinValue
填充字段留空的更合理
而不是使用DateTime.now,因为它更容易将其识别为“伪空值”(并且如果需要将其转换为父对象的部分类中的实际null)
首先使用Entity框架代码时,请将其声明为:
public Nullable<System.DateTime> LastLogin { get; set; }
您的实体中是否存在ModifiedTime属性,仅在数据库端更新? 如果是这样,您必须使用DatabaseGeneratedOption.Computed(对于EF CodeFirst)。 另请访问此https://stackoverflow.com/a/9508312/1317263
谢谢。
我们遇到了同样的问题。 这与mssql版本有关。 我们使用此方法使其适用于所有版本。
使用xml编辑器打开edmx文件在文件顶部找到此行
<Schema Namespace="XXXXX.Store" Alias="Self" Provider="System.Data.SqlClient" ProviderManifestToken="2008"
将2008替换为2005保存文件,重新编译项目。
希望能在未来帮助别人。
我只用dbfirst approche尝试过这个解决方案。
在尝试解决这个问题好几天之后我使用了DateTime?
作为我的模型中的实体框架代码优先而不是DateTime
的数据类型。
确保在插入/更新时没有遗漏DB(datetime)中的任何非空字段。 我有相同的错误,并在向这些日期时间字段插入值时,问题已得到解决。如果没有为非null的datetime字段分配正确的值,则会发生这种情况。
不适合日期时间适合日期时间2数据类型,反之亦然,情况并非如此,您可以将日期1月1500日期保留在datetime2数据类型中,但日期时间仅返回1753,日期时间2列可以返回所有今年的方式1.我会检查你传递的最小日期是什么,以及你的表是否有datetime2或datetime数据类型列
我在ASP.Net MVC应用程序中遇到了同样的问题。
我的应用程序中有两个具有DateTime属性的模型类。
在调查时,我注意到一个模型的DateTime属性可以为空,即使其成为Birth可选属性的日期
另一个模型具有DateTime属性和必需的数据注释(保存此模型时出错)
我的应用程序是代码优先,所以我通过将数据类型设置为DateTime2来解决问题
[Column(TypeName="datetime2")]
然后我在包管理器控制台上运行了迁移。
简单。 首先在代码中,将DateTime的类型设置为DateTime?。 因此,您可以在数据库中使用可空的DateTime类型。
这是继stepanZ的答案......我在使用AutoMapper
Entity Framework Code First
时遇到了这个错误。
在设置AutoMapping
我们createddt
, updateddt
, createdby
和updatedby
字段,这些字段在我们的public override int SaveChanges()
函数中自动设置。 执行此操作时,您需要确保将这些字段设置为AutoMapper
忽略,否则当这些字段未从View
提供时,数据库将更新为null
。
我的问题是我将源和目标放在错误的方式,因此在设置ViewModel
时尝试忽略字段,而不是在设置Model
。
当我收到此错误时, Mapping
看起来像这样(注意:第二行的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());
两种解决方案
在类中声明属性,如下所示,并创建一个update-database:
public DateTime? MyDate {get; set;}
或者在填充数据库的Seed方法中设置属性的日期,不需要update-database:
context.MyClass.AddOrUpdate(y => y.MyName,new MyClass { MyName = "Random", MyDate= DateTime.Now })
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.