eri*_*007 58 c# sql-server datetime linq-to-sql
是不是有一种(简单)方法告诉Linq To SQL类特定的DateTime属性应该被视为UTC(即默认情况下将DateTime类型的Kind属性设置为Utc),或者是否存在"干净"的解决方法?
我的app-server上的时区与SQL 2005 Server不同(不能更改任何),没有一个是UTC.当我将类型为DateTime的属性保留为dB时,我使用UTC值(因此db列中的值为UTC),但是当我读回值时(使用Linq To SQL),我得到DateTime的.Kind属性值为'未指定'.
问题是,当我将它'转换为UTC时,它是4小时关闭.这也意味着当它被序列化时,它最终在客户端以4小时的错误偏移(因为它使用UTC序列化).
Rob*_*los 37
生成的LinqToSql代码提供了可扩展性点,因此您可以在加载对象时设置值.
关键是创建一个扩展生成的类的OnLoadedpartial 类,然后实现partial方法.
例如,假设你的类是Person,所以你有一个生成的部分Person类Blah.designer.cs.
通过创建新类(必须位于不同的文件中)来扩展分部类,如下所示:
public partial class Person {
partial void OnLoaded() {
this._BirthDate = DateTime.SpecifyKind(this._BirthDate, DateTimeKind.Utc);
}
}
Run Code Online (Sandbox Code Playgroud)
Joe*_*Joe 28
SQL Server DateTime不包含任何时区或DateTimeKind信息,因此从数据库中检索的DateTime值正确具有Kind = DateTimeKind.Unspecified.
如果您希望将这些时间设为UTC,则应按如下方式"转换"它们:
DateTime utcDateTime = new DateTime(databaseDateTime.Ticks, DateTimeKind.Utc);
Run Code Online (Sandbox Code Playgroud)
或等效的:
DateTime utcDateTime = DateTime.SpecifyKind(databaseDateTime, DateTimeKind.Utc);
Run Code Online (Sandbox Code Playgroud)
我假设你的问题是你试图将它们转换如下:
DateTime utcDateTime = databaseDateTime.ToUniversalTime();
Run Code Online (Sandbox Code Playgroud)
这看起来似乎是合理的,但是根据DateTime.ToUniversalTime的MSDN文档,在转换其类型未指定的DateTime时:
假定当前DateTime对象是本地时间,并且执行转换,就像Kind是Local一样.
此行为是与.NET 1.x向后兼容所必需的,它没有DateTime.Kind属性.
对于我们的情况,总是如前所述指定DateTimeKind是不切实际的:
DateTime utcDateTime = DateTime.SpecifyKind(databaseDateTime, DateTimeKind.Utc);
Run Code Online (Sandbox Code Playgroud)
我们正在使用Entity Framework,但这应该类似于Linq-to-SQL
如果要强制将来自数据库的所有DateTime对象指定为UTC,则需要添加T4转换文件并为所有DateTime和可为空的DateTime对象添加其他逻辑,以便将它们初始化为DateTimeKind.Utc
我有一篇博文,一步一步解释:http://www.aaroncoleman.net/post/2011/06/16/Forcing-Entity-Framework-to-mark-DateTime-fields-at-UTC.aspx
简而言之:
1)为.edmx模型创建.tt文件(或者为Linq-to-SQL创建.dbml)
2)打开.tt文件并找到"WritePrimitiveTypeProperty"方法.
3)替换现有的setter代码.这是ReportPropertyChanging 和ReportPropertyChanged方法回调之间的所有内容,具有以下内容:
<#+ if( ((PrimitiveType)primitiveProperty.TypeUsage.EdmType).PrimitiveTypeKind == PrimitiveTypeKind.DateTime)
{
#>
if(<#=code.FieldName(primitiveProperty)#> == new DateTime())
{
<#=code.FieldName(primitiveProperty)#> = StructuralObject.SetValidValue(value<#=OptionalNullableParameterForSetValidValue(primitiveProperty, code)#>);
<#+
if(ef.IsNullable(primitiveProperty))
{
#>
if(value != null)
<#=code.FieldName(primitiveProperty)#> = DateTime.SpecifyKind(<#=code.FieldName(primitiveProperty)#>.Value, DateTimeKind.Utc);
<#+ }
else
{#>
<#=code.FieldName(primitiveProperty)#> = DateTime.SpecifyKind(<#=code.FieldName(primitiveProperty)#>, DateTimeKind.Utc);
<#+
}
#>
}
else
{
<#=code.FieldName(primitiveProperty)#> = StructuralObject.SetValidValue(value<#=OptionalNullableParameterForSetValidValue(primitiveProperty, code)#>);
}
<#+
}
else
{
#>
<#=code.FieldName(primitiveProperty)#> = StructuralObject.SetValidValue(value<#=OptionalNullableParameterForSetValidValue(primitiveProperty, code)#>);
<#+
}
#>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15208 次 |
| 最近记录: |