Pugz
Pugz

Reputation: 1029

Custom Value Types in Entity Framework

I'd like to use a custom value type as detailed here http://vbcity.com/blogs/jatkinson/archive/2010/01/12/create-custom-types-and-initialize-them-without-the-new-keyword-c-vb-net.aspx]1 in Entity Framework. They underlying type is an enum so I'd like to store the whole thing in the database as an int, the enum's base type. The purpose of the custom value type is for retrieving string values from a dictionary that's mapped to the enum values. When I use the custom value type in EF code first as a property of an entity the database column is not generated. Also, when looking at the model with EF power tools that property does not show up.

Here's my custom value type:

public struct AttachmentType
{
    private AttachmentType(AttachmentTypeCode attachmentTypeCode)
    {
        if (CodesValues.ContainsKey(attachmentTypeCode))
        {
            _val = attachmentTypeCode;
        }
        else
        {
            throw new InvalidEnumArgumentException("This is not a valid attachment type code.");
        }

    }

    public override string ToString()
    {
        return CodesValues[_val];
    }

    private AttachmentTypeCode _val;

    public static implicit operator AttachmentType(AttachmentTypeCode attachmentTypeCode)
    {
        return new AttachmentType(attachmentTypeCode);
    }

    private static readonly Dictionary<AttachmentTypeCode, string> CodesValues = new Dictionary<AttachmentTypeCode, string>()
    {
        {AttachmentTypeCode.Email, "Electronic Mail Message"},
        {AttachmentTypeCode.WordDocument, "Microsoft Word 2007 Document"},
        {AttachmentTypeCode.PDF, "Adobe PDF Document"},
    };

    public enum AttachmentTypeCode
    {
        Email= 1,
        WordDocument= 2,
        PDF = 3
    }
}

Upvotes: 1

Views: 2043

Answers (1)

Pugz
Pugz

Reputation: 1029

The answer to this problem is to treat the class as a complex type via annotation or Fluent API, add a public property with a getter of the enum type to access the internal private property, and add a custom code-first configuration like the following to map the public property just created (in my case an enum, which EF5 supports) of the complex type to a database field:

modelBuilder.Types<ClassAttachmentTypeIsUsedIn>()
.Configure(ctc => ctc.Property(cust => cust.AttachmentType.EnumProperty)
.HasColumnName("AttachmentType"));

see more here: http://visualstudiomagazine.com/articles/2014/04/01/making-complex-types-useful.aspx

Upvotes: 2

Related Questions