views:

44

answers:

2

Entity framework maps DB types to .NET types, for instance SQL Server's BigInt is mapped to .NET's long.

Is it possible to create a new type and have a store type (such as BigInt or VarChar) mapped to it? If so, how?

FYI, my goal is to change the way the .NET scalar writes its value to the query, and specifically the way its default value is written (I'm trying to use SQL Server's default keyword to solve problem such as this).

Thanks,
Asaf

Update
Found a post for EF 1 saying it can't be done. I'm not sure it's correct for its time, and I'm even less sure it's relevant for EF 4.

+1  A: 

I'm almost sure you can't create new scalar types even in EF4.0.

What you actually can do is to create a Complex type wrapping underlying scalar type. Complex types are supported by designer in VS2010.

<ComplexType Name="DateTimeWrapper" >
  <Property Type="DateTime" Name="Value" Nullable="false" />
</ComplexType>

Provide any default value you want and a couple of implicit conversion operators.

public class DateTimeWrapper
    {
        private DateTime _value = DateTime.Now;

        public DateTime Value
        {
            get { return _value; }
            set { _value = value; }
        }

        public static implicit operator DateTime(DateTimeWrapper wrapper)
        {
            if (wrapper == null) return DateTime.Now;
            return wrapper.Value;
        }

        public static implicit operator DateTimeWrapper(DateTime date)
        {
            return new DateTimeWrapper { Value = date };
        }
    }

So every entity having complex property of DateTimeWrapper type will be correctly initialized. And you can use syntax like this: MyEntity.MyDateTimeWrapperProp = DateTime.UtcNow when creating and modifying entities.

But in queries you'll have to write MyEntities.Where(ent => ent.MyDateTimeWrapperProp.Value == ...).

Yury Tarabanko
A: 

Short answer: There's no simple way to do it.

Long answer

An entity framework model is described using 3 sub-languages - SSDL, CSDL and MSL.

At the conceptual level (CSDL) - the property element's type would be the place to this. A property element's type can be either one of the predefined EDMSimpleType values, or a ComplexType, which is a collection of ComplexType and EDMSimpleType elements. The CSDL level is not the place to do this.

The mapping level (MSL) just matches storage elements and conceptual elements. There's no place here to do this.

We're left with the storage level (SSDL). SSDL property element's type is not strictly defined in MSDN, and in any case it might be possible to override the provider layer to give different functionality for existing types. But, it's not trivial and not recommended.

Conclusion: There's no practical way to add new scalar types (other than a straight forward collection of simple types, i.e. ComplexType).

Asaf R