2012年5月11日 星期五

如何在 Entity Framework 4.3.1 上使用 enum

使用 Entity Framework 來存取資料實在是很方便,但如果要用 enum 時就不能 work  了。

Entity Framework 5.0 支援 Enum

在尚未上市的 VS11 中,就直接支援了 enum。當然需要用  NuGet 安裝  Entity Framework

image

public class AuditLog
  {
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    [Required]
    public string Account { get; set; }
    [Column("AuditTime")]

    public DateTime Date { get; set; }
    [MaxLength(10)]
    public string GroupName { get; set; }

    public int FunctionId { get; set; }

    public AuditStatus Status { get; set; }

    public override string ToString()
    {
      return string.Format("Id={0}, Account={1}, Date={2}, GroupName={3}, FunctionId={4}, Status={5}", Id, Account, Date, GroupName, FunctionId, Status);
    }
  }

  public class BasicContext : System.Data.Entity.DbContext
  {
    public BasicContext(string dbName)
      : base(dbName)
    { }

    public DbSet<AuditLog> AuditLogs { get; set; }
  }

  public enum AuditStatus
  {
    Success,
    Fail
  }

呼叫的方式也非常簡單,就與一般 c# 沒差。

static void Main(string[] args)
    {
      Database.SetInitializer<BasicContext>(new DropCreateDatabaseIfModelChanges<BasicContext>());
      using (var context = new BasicContext("DbName"))
      {
        bool isCreated = context.Database.CreateIfNotExists();
        Console.WriteLine(isCreated);
        var audit = new AuditLog() { Account = "E", Date = DateTime.Now, FunctionId = 1, Status = AuditStatus.Fail };
        context.AuditLogs.Add(audit);
        context.SaveChanges();

        var q = from i in context.AuditLogs
                select i;
        foreach (var auditLog2 in q)
          Console.WriteLine(auditLog2);
      }
    }

產生得資料庫如下圖

image

Entity Framework 4.3.1 的方式

相同的程式,在  4.3.1 版以前是沒有作用的。 Entity Framework 對不支援的欄位,就視而不見,因此相同的程式,在資料庫中就是看不到 Status 的欄位。

有沒有什麼變通方法嗎?有! 只需要改一下屬性存取方式即可。程式如下

public int StatusValue { get; set; }

    public AuditStatus Status
    {
      get { return (AuditStatus)StatusValue; }
      set { StatusValue = (int) value; }
    }

程式寫作時,是透過  Status 來存取,但 Entity Framework 看不懂 AuditStatus 欄位,因此就不理 Status 欄位了。取而代之,是產生 StatusValue 欄位

結果如下

image

 

如果想要產生 Status 欄位呢?再變通一下

[Column("Status")]
    public int StatusValue { get; set; }

    [NotMapped]
    public AuditStatus Status
    {
      get { return (AuditStatus)StatusValue; }
      set { StatusValue = (int) value; }
    }
上述的屬性(Attribute) 告訴 entity framework,Status 這個 enum Property 不必理會。而 StatusValue 這個 int Property 要對應到資料表的 Status 欄位。

沒有留言:

Share with Facebook