这是您可能会考虑的一种方法:
首先,定义以下属性:
[AttributeUsage(AttributeTargets.Property)]
public class DateTimeKindAttribute : Attribute
{
private readonly DateTimeKind _kind;
public DateTimeKindAttribute(DateTimeKind kind)
{
_kind = kind;
}
public DateTimeKind Kind
{
get { return _kind; }
}
public static void Apply(object entity)
{
if (entity == null)
return;
var properties = entity.GetType().GetProperties()
.Where(x => x.PropertyType == typeof(DateTime) || x.PropertyType == typeof(DateTime?));
foreach (var property in properties)
{
var attr = property.GetCustomAttribute<DateTimeKindAttribute>();
if (attr == null)
continue;
var dt = property.PropertyType == typeof(DateTime?)
? (DateTime?) property.GetValue(entity)
: (DateTime) property.GetValue(entity);
if (dt == null)
continue;
property.SetValue(entity, DateTime.SpecifyKind(dt.Value, attr.Kind));
}
}
}
现在将该属性与您的 EF 上下文挂钩:
public class MyContext : DbContext
{
public DbSet<Foo> Foos { get; set; }
public MyContext()
{
((IObjectContextAdapter)this).ObjectContext.ObjectMaterialized +=
(sender, e) => DateTimeKindAttribute.Apply(e.Entity);
}
}
现在在任何DateTime
或DateTime?
属性上,您可以应用此属性:
public class Foo
{
public int Id { get; set; }
[DateTimeKind(DateTimeKind.Utc)]
public DateTime Bar { get; set; }
}
有了这个,每当实体框架从数据库加载一个实体时,它都会设置DateTimeKind
你指定的,比如 UTC。
现在,你说你想开始切换到DateTimeOffset
类型。您可以利用DateTime
具有单向隐式转换的事实,DateTimeOffset
这将考虑.Kind
在内。换句话说,您可以这样做:
DateTimeOffset BarDTO = foo.Bar;
即使foo.Bar
是 a DateTime
,这也会起作用。因为种类设置为 UTC,所以偏移量将在DateTimeOffset
.
当然,你总是可以在你的模型中这样做:
[NotMapped]
public DateTimeOffset BarDTO
{
get { return Bar; }
set { Bar = value.UtcDateTime; }
}
我相信您可以根据自己的需要对此进行修改。主要的是,无论属性映射到该字段,类型都必须匹配。