飞鸽传书:浅谈枚举

来源:互联网 发布:不锈钢计算软件 编辑:程序博客网 时间:2024/06/04 00:56

飞鸽传书:浅谈枚举

枚举——你是那温柔的陷阱吗?最近在园子里看了两篇关于枚举的文章《小心枚举陷阱》和《温柔的枚举陷阱》,说的都是一个问题:前台绑定枚举,数据库中存储枚举的值,当枚举更新后,数据库中的值却没有更新,于是引起了一堆数据不对应的问题。

在系统中,我们肯定都遇到过用枚举来储存数据的情况,如下图,需要显示的是学历,但学历这东西毕竟不是经常改,所以就用枚举吧,放在数据库中,还要新建一张表,还要左联,太麻烦。

 

如是就有了以下代码:

view sourceprint?1 public enum EStueType { 小学, 中学, 大学, }

   然后数据库中存储的就是0、1、2,用来分别表示小学、中学、大学。

  但后来,新的需求来了,需要将中学变为初中和高中。有人想当然,直接将“中学”改成“初中”,然后再在“初中”和“大学”之间加一个“高中”,编译无误,OK,挂到服务器上了。

后来客户反应,噫?我以前不是填的大学吗?现在怎么变成高中生了啊?管理员拿个VS编译半天,终于发现,原来添加了一个“高中”后,“高中”的值变为2 了,也就是说数据库中原来的所有学历为2(以前表示的是大学生),现在都变成高中生了。哎,都是这温柔的枚举惹的祸啊,于是开始摈弃枚举。

 

  解决这个问题常用的做法有两种:

  1.新建一张表,专门用来存储学历

  2.接着用那温柔的枚举。

  

  第一种方法很好的解决了这个问题,但问题在于会在数据库中新建表,并且是一张更新不多的表,另一个问题是如果数据量大时,左联会影响性能。

  第二种方法就需要我们很好的解决枚举的问题了,下面我就讲我用枚举时的做法。

  

  用枚举时我们也有两种做法:第一:将枚举显示赋值:如下:

    public enum EStueType
        {
            小学=0,
            中学=1,
            大学=2,
        }

  OK,你要新加一个高中对吧,难不到我:

   public enum EStueType
        {
            小学=0,
             初中=1,

               高中=3,
            大学=2,
        }
   新问题:dbo查数据:select * from [表名],然后发现用户的学历这儿,一夫0123想当然的他认为

     0代表小学

    1代表初中

    2代表高中

    3代表大学

   OK,他接下的操作就极具危险性了:他要对所有的大学生进行一次“婚前性教育培训课”,结果...........

  

  于是,我们想着,要不我们数据库中直接存储枚名称,而不是值,也就是表中学历字段直接存储如“大学”。  

  嗯,这个办法不错,问题都解决了。

  但好像我们学编程的第一节课老师就说了:不要用中文。有两个原因:

  1.中文占用更多的数据库空间

  2.中文编程总让人感觉不是那么专业飞鸽传书

  

  于是我就想:如何实现这样的效果呢:数据库中只存储英文名称:如University,别人一看就知道大学,但前台上,我要显示的是“大学”两个汉字,飞鸽传书如下:

  

  于是我就编写了一个枚举的通用类:

  

枚举操作类
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Reflection;using System.Data;using System.Windows.Forms;namespace WindowsFormsApplication1{    public class EnumUtils<Tenum>    {        public static DataTable GetAllEnums()        {            Type t = typeof(Tenum);            FieldInfo[] fieldInfoList = t.GetFields();            DataTable dt = new DataTable();            dt.Columns.Add("Text", typeof(string));            dt.Columns.Add("Value", typeof(string));            foreach (FieldInfo tField in fieldInfoList)            {                if (!tField.IsSpecialName)                {                    DataRow dr = dt.NewRow();                    dr["Value"] = tField.Name;                    EnumDescriptionAttribute[] enumAttributelist = (EnumDescriptionAttribute[])tField.GetCustomAttributes(typeof(EnumDescriptionAttribute), false);                    if (enumAttributelist != null && enumAttributelist.Length > 0)                    {                        dr["Text"] = enumAttributelist[0].Description;                    }                    else                    {                        dr["Text"] = tField.Name;                    }                    dt.Rows.Add(dr);                }            }            return dt;        }        public static string GetText(Tenum enumInstance)        {            Type t = typeof(Tenum);            FieldInfo[] fieldInfoList = t.GetFields();            string strReturn = string.Empty;            foreach (FieldInfo tField in fieldInfoList)            {                if (!tField.IsSpecialName && tField.Name.ToLower() == enumInstance.ToString().ToLower())                {                    EnumDescriptionAttribute[] enumAttributelist = (EnumDescriptionAttribute[])tField.GetCustomAttributes(typeof(EnumDescriptionAttribute), false);                    if (enumAttributelist != null && enumAttributelist.Length > 0)                    {                        strReturn = enumAttributelist[0].Description;                        break;                    }                }            }            return strReturn;        }        public static string GetValue(Tenum enumInstance)        {            Type t = typeof(Tenum);            FieldInfo[] fieldInfoList = t.GetFields();            string strReturn = string.Empty;            foreach (FieldInfo tField in fieldInfoList)            {                if (!tField.IsSpecialName && tField.Name.ToLower() == enumInstance.ToString().ToLower())                {                    strReturn = tField.Name;                    break;                }            }            return strReturn;        }        public static Tenum GetEnum(string Value)        {            Type t = typeof(Tenum);            FieldInfo field = t.GetField(Value);            return (Tenum)System.Enum.Parse(t, Value);        }        public static void BindListControl(ListControl listControl)        {            listControl.DisplayMember = "Text";            listControl.ValueMember = "Value";            listControl.DataSource = GetAllEnums();        }    }    [AttributeUsage(AttributeTargets.Enum | AttributeTargets.Field, AllowMultiple = false)]    public class EnumDescriptionAttribute : Attribute    {        private string description;        public string Description        {            get            {                return this.description;            }        }        public EnumDescriptionAttribute(string description)            : base()        {            this.description = description;        }    }}
 

 

 飞鸽传书枚举申明时如下:

 

代码
        public enum EStueType        {            [EnumDescription("小学")]            Primaryschool,            [EnumDescription("初中")]            JuniorHighSchool,            [EnumDescription("大学")]            HighSchool,            [EnumDescription("大学")]            University        }
 

 飞鸽传书:http://www.freeeim.com/

 前台绑定时:EnumUtils<EStueType>.BindListControl(this.comboBox1);

获得绑定值时(枚举类型): EnumUtils<EStueType>.GetEnum(this.comboBox1.SelectedValue.ToString());;

获得显示值时(枚举显示名称):EnumUtils<EStueType>.GetText(EStueType.HighSchool);

 

示例效果如下:


OK,一切问题解决

原创粉丝点击