代码之家  ›  专栏  ›  技术社区  ›  Sander Rijken

确保DateTime属性返回DateTimeKind.Utc

  •  4
  • Sander Rijken  · 技术社区  · 15 年前

    Kind == DateTimeKind.Utc

    如果可能使用t4,请描述如何更改属性。当前,属性生成为:

    [EdmScalarPropertyAttribute(EntityKeyProperty=false, IsNullable=false)]
    [DataMemberAttribute()]
    public global::System.DateTime Created
    {
        get
        {
            return _created;
        }
        internal set
        {
            OnCreatedChanging(value);
            ReportPropertyChanging("Created");
            _created = StructuralObject.SetValidValue(value);
            ReportPropertyChanged("Created");
            OnCreatedChanged();
        }
    }
    private global::System.DateTime _created;
    partial void OnCreatedChanging(global::System.DateTime value);
    partial void OnCreatedChanged();
    
    3 回复  |  直到 15 年前
        1
  •  8
  •   aarondcoleman    13 年前

    在我们的案例中,始终指定DateTimeKind是不切实际的,如前所述:

    DateTime utcDateTime = DateTime.SpecifyKind(databaseDateTime, DateTimeKind.Utc);
    

    http://www.aaroncoleman.net/post/2011/06/16/Forcing-Entity-Framework-to-mark-DateTime-fields-at-UTC.aspx

    简言之:

    1) 为.edmx模型创建.tt文件

    2) 打开.tt文件并找到“WritePrimitiveTypeProperty”方法。

    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)#>);
    <#+ 
            }
    #>
    
        2
  •  12
  •   Community CDub    7 年前

    我使用了与Michael相同的方法(参见其他博客文章: https://stackoverflow.com/a/9386364/1069313 )直到那时,我才深入一点,使用反射搜索DateTime和DateTime?

    public static void ReadAllDateTimeValuesAsUtc(this DbContext context)
    {
            ((IObjectContextAdapter)context).ObjectContext.ObjectMaterialized += ReadAllDateTimeValuesAsUtc;
    }
    
    private static void ReadAllDateTimeValuesAsUtc(object sender, ObjectMaterializedEventArgs e)
    {
        //Extract all DateTime properties of the object type
        var properties = e.Entity.GetType().GetProperties()
            .Where(property => property.PropertyType == typeof (DateTime) ||
                               property.PropertyType == typeof (DateTime?)).ToList();
        //Set all DaetTimeKinds to Utc
        properties.ForEach(property => SpecifyUtcKind(property, e.Entity));
    }
    
    private static void SpecifyUtcKind(PropertyInfo property, object value)
    {
        //Get the datetime value
        var datetime = property.GetValue(value, null);
    
        //set DateTimeKind to Utc
        if (property.PropertyType == typeof(DateTime))
        {
            datetime = DateTime.SpecifyKind((DateTime) datetime, DateTimeKind.Utc);
        }
        else if(property.PropertyType == typeof(DateTime?))
        {
            var nullable = (DateTime?) datetime;
            if(!nullable.HasValue) return;
            datetime = (DateTime?)DateTime.SpecifyKind(nullable.Value, DateTimeKind.Utc);
        }
        else
        {
            return;
        }
    
        //And set the Utc DateTime value
        property.SetValue(value, datetime, null);
    }
    

    然后我转到我的WebsiteReadModelContext的构造函数,它是一个DbContext对象,并调用ReadAllDateTimeValuesAsUtc方法

    public WebsiteReadModelContext()
    {
          this.ReadAllDateTimeValuesAsUtc();
    }