Вот один подход можно рассмотреть:
Во-первых, определить это следующий атрибут:
[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; }
}
с этим на месте, когда Entity Framework загружает объект из базы данных он установит указанный вами DateTimeKind
, например, UTC.
Теперь вы сказали, что хотите переключиться на DateTimeOffset
. Вы можете воспользоваться тем фактом, что DateTime
имеет одностороннее неявное преобразование в DateTimeOffset
, которое учитывает .Kind
. Другими словами, вы можете сделать это:
DateTimeOffset BarDTO = foo.Bar;
Несмотря на то, foo.Bar
является DateTime
, это будет работать. Поскольку тип установлен в UTC, смещение будет установлено на ноль в DateTimeOffset
.
Конечно, вы всегда можете сделать это в вашей модели с чем-то вроде этого:
[NotMapped]
public DateTimeOffset BarDTO
{
get { return Bar; }
set { Bar = value.UtcDateTime; }
}
Я уверен, что вы можете придумать вариации на это в соответствии с вашими потребностями. Главное, что любое свойство сопоставляется с полем, тип должен совпадать.
simular question http://stackoverflow.com/questions/9389954/entity-framework-mapping-datetimeoffset-to-sql-server-datetime –
@ArsenMrkt - Если я следую принятому ответу в этой теме, я получаю новый error: «Свойство CreateDate не является объявленным свойством в типе« {ObjectType} ». Убедитесь, что свойство не было явно исключено из модели с помощью аннотации Ignore или NotMappedAttribute. Убедитесь, что он действителен примитивное свойство ". – Russ