Jef*_*ito 5 asp.net entity-framework sql-server-2012
当我Buyin
从ASP.NET MVC控制器创建一个对象的响应时,(return Json(response, JsonRequestBehavior.AllowGet);
看起来像这样:
"Buyin": {
"Id": 95,
"PlayerSessionId": 88,
"PlayerId": 45,
"PlayerName": "Alan",
"Amount": 888,
"BuyinType": "Credits",
"Description": null,
"Authorized": true,
"SignPath": "~/Signs/Buyins\\95.png",
"Payment": null,
"CreationDate": "/Date(1477242738042)/"
},
Run Code Online (Sandbox Code Playgroud)
如果我在Epoch Converter上转换它,我会得到这个时间:GMT: Sun, 23 Oct 2016 17:12:18.042 GMT
在数据库中查看存储的日期时间似乎是正确的:
95 NULL 1 1 2016-10-23 17:12:18.043
Run Code Online (Sandbox Code Playgroud)
发送响应时,Kind
将设置为UTC
.
现在我调用一个控制器来获取我的所有数据,并且所有日期都有几个小时添加到它:
{
"Id": 95,
"PlayerSessionId": 88,
"PlayerId": 45,
"PlayerName": "Alan",
"Amount": 888,
"BuyinType": "Credits",
"Description": null,
"Authorized": true,
"SignPath": "~/Signs/Buyins\\95.png",
"Payment": null,
"CreationDate": "/Date(1477267938043)/"
}
Run Code Online (Sandbox Code Playgroud)
1477267938043
= GMT: Mon, 24 Oct 2016 00:12:18.043 GMT
但是,当我请求此对象时,我可以看到实际对象具有正确的日期设置:
但这Kind
是设定的,Unspecified
所以我认为这是导致问题的原因.
目前我还没有设置任何全球化设置.
所以基本上我的问题是:当ASP.NET MVC从数据库加载日期时有一种方法告诉服务器加载日期Kind
设置UTC
为我认为这是问题吗?
使用Entity Framework保存和加载数据库.
在接受的答案后更新
接受的答案很棒但是我的日期值已经作为UTC日期存储在数据库中,所以我修改GetDateTime
为:
public override DateTime GetDateTime(int ordinal)
{
var date = base.GetDateTime(ordinal);
var utcDate = DateTime.SpecifyKind(date, DateTimeKind.Utc);
return utcDate;
//return base.GetDateTime(ordinal).ToUniversalTime();
}
Run Code Online (Sandbox Code Playgroud)
Iva*_*oev 19
假设您正在使用EF6,并且您想要将从数据库检索到的Kind
任何DateTime
值的属性设置为Utc
.
已经提出了类似的问题,答案倾向于暗示ObjectContext.ObjectMaterialized
事件,但它并没有触发使用投影的查询.
我将提出的解决方案适用于实体和投影查询,通过在DbDataReader
级别执行转换(由此类查询使用).
为了做到这一点,我们需要一个DbDataReader
截取GetDateTime
方法的自定义实现.不幸的是,实现DbDataReader
派生类需要大量的样板代码.幸运的是,我已经创建了一个基类来形成我对Dynamic Translate的回答,以避免C#语法错误,它只是将每个方法委托给底层DbDataReader
实例,所以我将从那里开始:
abstract class DelegatingDbDataReader : DbDataReader
{
readonly DbDataReader source;
public DelegatingDbDataReader(DbDataReader source)
{
this.source = source;
}
public override object this[string name] { get { return source[name]; } }
public override object this[int ordinal] { get { return source[ordinal]; } }
public override int Depth { get { return source.Depth; } }
public override int FieldCount { get { return source.FieldCount; } }
public override bool HasRows { get { return source.HasRows; } }
public override bool IsClosed { get { return source.IsClosed; } }
public override int RecordsAffected { get { return source.RecordsAffected; } }
public override bool GetBoolean(int ordinal) { return source.GetBoolean(ordinal); }
public override byte GetByte(int ordinal) { return source.GetByte(ordinal); }
public override long GetBytes(int ordinal, long dataOffset, byte[] buffer, int bufferOffset, int length) { return source.GetBytes(ordinal, dataOffset, buffer, bufferOffset, length); }
public override char GetChar(int ordinal) { return source.GetChar(ordinal); }
public override long GetChars(int ordinal, long dataOffset, char[] buffer, int bufferOffset, int length) { return source.GetChars(ordinal, dataOffset, buffer, bufferOffset, length); }
public override string GetDataTypeName(int ordinal) { return source.GetDataTypeName(ordinal); }
public override DateTime GetDateTime(int ordinal) { return source.GetDateTime(ordinal); }
public override decimal GetDecimal(int ordinal) { return source.GetDecimal(ordinal); }
public override double GetDouble(int ordinal) { return source.GetDouble(ordinal); }
public override IEnumerator GetEnumerator() { return source.GetEnumerator(); }
public override Type GetFieldType(int ordinal) { return source.GetFieldType(ordinal); }
public override float GetFloat(int ordinal) { return source.GetFloat(ordinal); }
public override Guid GetGuid(int ordinal) { return source.GetGuid(ordinal); }
public override short GetInt16(int ordinal) { return source.GetInt16(ordinal); }
public override int GetInt32(int ordinal) { return source.GetInt32(ordinal); }
public override long GetInt64(int ordinal) { return source.GetInt64(ordinal); }
public override string GetName(int ordinal) { return source.GetName(ordinal); }
public override int GetOrdinal(string name) { return source.GetOrdinal(name); }
public override string GetString(int ordinal) { return source.GetString(ordinal); }
public override object GetValue(int ordinal) { return source.GetValue(ordinal); }
public override int GetValues(object[] values) { return source.GetValues(values); }
public override bool IsDBNull(int ordinal) { return source.IsDBNull(ordinal); }
public override bool NextResult() { return source.NextResult(); }
public override bool Read() { return source.Read(); }
public override void Close() { source.Close(); }
public override T GetFieldValue<T>(int ordinal) { return source.GetFieldValue<T>(ordinal); }
public override Task<T> GetFieldValueAsync<T>(int ordinal, CancellationToken cancellationToken) { return source.GetFieldValueAsync<T>(ordinal, cancellationToken); }
public override Type GetProviderSpecificFieldType(int ordinal) { return source.GetProviderSpecificFieldType(ordinal); }
public override object GetProviderSpecificValue(int ordinal) { return source.GetProviderSpecificValue(ordinal); }
public override int GetProviderSpecificValues(object[] values) { return source.GetProviderSpecificValues(values); }
public override DataTable GetSchemaTable() { return source.GetSchemaTable(); }
public override Stream GetStream(int ordinal) { return source.GetStream(ordinal); }
public override TextReader GetTextReader(int ordinal) { return source.GetTextReader(ordinal); }
public override Task<bool> IsDBNullAsync(int ordinal, CancellationToken cancellationToken) { return source.IsDBNullAsync(ordinal, cancellationToken); }
public override Task<bool> ReadAsync(CancellationToken cancellationToken) { return source.ReadAsync(cancellationToken); }
public override int VisibleFieldCount { get { return source.VisibleFieldCount; } }
}
Run Code Online (Sandbox Code Playgroud)
并构建我们需要的实际类:
class UtcDateTimeConvertingDbDataReader : DelegatingDbDataReader
{
public UtcDateTimeConvertingDbDataReader(DbDataReader source) : base(source) { }
public override DateTime GetDateTime(int ordinal)
{
return DateTime.SpecifyKind(base.GetDateTime(ordinal), DateTimeKind.Utc);
}
}
Run Code Online (Sandbox Code Playgroud)
一旦我们有了这个,我们需要使用EF 拦截将其插入EF基础设施.
我们首先创建一个自定义DbCommandInterceptor
派生类:
class UtcDateTimeConvertingDbCommandInterceptor : DbCommandInterceptor
{
public override void ReaderExecuted(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext)
{
base.ReaderExecuted(command, interceptionContext);
if (interceptionContext.Result != null && interceptionContext.Exception == null)
interceptionContext.Result = new UtcDateTimeConvertingDbDataReader(interceptionContext.Result);
}
}
Run Code Online (Sandbox Code Playgroud)
注册它(例如从你的DbContext
派生类静态构造函数):
public class YourDbContext : DbContext
{
static YourDbContext()
{
DbInterception.Add(new UtcDateTimeConvertingDbCommandInterceptor());
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
我们完成了.
现在DateTime
,来自数据库的每个值都将Kind
属性设置为Utc
.
归档时间: |
|
查看次数: |
3063 次 |
最近记录: |