views:

60

answers:

1

I "inherited" an old Database where dates are stored as Int32 values (times too, but dates shall suffice for this example) i.e. 20090101 for Jan. 1st 2009. I can not change the schema of this database because it is still accessed by the old programs.
However I want to write a new program using EF as the O/R-M.
Now I'd love to have DateTime-Values in my Model.

Is there a way to write a custom type and use this as a Type in the EF-Model.

Something like a Type "OldDate"
with properties:
DatabaseValue : Int23
Value : DateTime (specifying the date-part whereas the time-part is always 0:00:00)

Is something like this possible with the EF-Model ?

Edit:
I think I found what I was looking for - but in NHibernate, so I'll rephrase:
Is something like NHIbernates IUserType possible with EF?

A: 

A ComlexType can manage this. I created a Type LeagcyDate which stores the int value in a DbData property and added an implicit conversion to and from Date. This approach seems reasonably manageble. Since EF4 ComplexTypes are supported in the Model-Designer, so adding one does no longer invoke tampering with the edmx.

The implicit Conversion I have done in a partial class like so:

    public partial class LegacyDate
    {
      public static implicit operator DateTime?(LegacyDate value)
      {
          return LegacyDateConverter.ToDate(value.DbData);
      }

      public static implicit operator LegacyDate(DateTime? value)
      {
          return new LegacyDate { DbData = LegacyDateConverter.ToLegacyDate(value) };
      }
   }

    internal static class LegacyDateConverter
    {
        public static DateTime? ToDate(int data)
        {
            if (data == 0) return null;
            int year = data/10000;
            int month = (data%10000)/100;
            int day = data/1000000;
            DateTime date;

            try
            {
                date = new DateTime(year, month, day);
            }
            catch (Exception e)
            {
                throw new ArgumentException(String.Format(
                    "Value {0} kan not be converted to DateTime", data), e);
            }
            return date;
        }

        public static int ToLegacyDate(DateTime? value)
        {
            int dateInt = 0;
            if (value.HasValue)
            {
                dateInt =
                value.Value.Year*10000 + value.Value.Month*100 + value.Value.Day;
            }
            return dateInt;            
        }
    }
Nils

related questions