[ Log On ]
แก้ขัดเรื่อง enum ใน EF Code First

Entity Framework (EF) เวอร์ชั่น ณ ขณะนี้ 4.3.1 ยังไม่สามารถรองรับการ map column กับ enum property ของ Code First ได้อย่างเต็มรูปแบบ แต่ได้รับการยืนยันจาก ทีมพัฒนาที่ Microsoft ว่ามันจะสามารถรองรับได้ในเวอร์ชั่น 5.0

ในกรณีที่เราต้องการ Code First ที่ทำงานกับ database เดิมที่มีการใช้งานอยู่แล้ว เราสามารถกำหนดให้ enum property ไป map กับ column นั้นๆ ได้เลย ไม่มีปัญหา แค่ cast value ให้ตรงกับ datatype ที่ระบุใน column นั้นก็เป็นอันใช้ได้

แต่ในกรณีที่เราต้องการ Code First และให้สร้าง database ใหม่จากนิยามที่เรากำหนดใน class นั้น EF ยังไม่รองรับการ map enum โดยตรง ลองพิจารณาจาก Person class

public interface IPerson
{
   Guid Id { get; set; }
   string Name { get; set; }
   GenderType Gender { get; set; }
}

ปกติผมชอบที่จะกำหนด interface เพื่อกำหนดทิศทางของโปรแกรมทั้งหมดก่อน และเพื่อให้ง่ายในการตรวจสอบ และ Automate Test ในภายหลัง เมื่อเรามี IPerson เรียบร้อยแล้ว ทีนี้ก็ implement กันต่อ

public class Person : IPerson
{
   [Key]
   public Guid Id { get; set; }
   public string Name { get; set; }
   public GenderType Gender { get; set; }
}

จะเห็นว่ามี GenderType เป็น enum อยู่ ซึ่งก็เป็น enum ธรรมดาๆ ดังนี้

public enum GenderType : byte { Male = 1, Femail = 2, NA = 3 }

การ map column ต่อให้ทำทั้ง DataAnnotation และ FluentAPI ก็จะพบว่ามันยัง error อยู่ ดังนั้นสิ่งที่ต้องทำคือการสร้าง proxy property ขึ้นมาช่วยงาน

public class Person : IPerson
{
   [Key]
   public Guid Id { get; set; }
   public string Name { get; set; }
   public byte Gender { get; set; }
   GenderType IPerson.Gender 
   {
      get { return (GenderType)this.Gender; }
      set { this.Gender = (byte)value; } 
   }
}
เท่านี้ก็สามารถใช้งาน enum ได้แล้วครับ ถึงมันจะวุ่นวายที่ต้องมาสร้าง proxy property แต่ถ้ามองถึงการตรวจสอบ code ที่จะอ่านง่ายขึ้นแล้ว มันก็คุ้มนะครับที่จะต้องใช้วิธีนี้ไปพลางๆ ระหว่างที่รอ EF 5 ออก
 
Happy Coding! :)