日期:2014-05-20  浏览次数:20478 次

共享我的实体类设计方法,请大家多多指教。
C# code

/*
 * 我是由ASP转C#的,写C#也有两三年了,也作过几个小项目,因为一直都是一个人开发,所以许多东西都是google或是自己琢磨的,基本上是举步艰难,不过还算是乐在其中吧。
 * 因为是作的项目比较小,所以实体类基本上是一个核心部份了,所以对这部份东西比较上心,但是,没人交流,故,也不知道到底怎么样。
 * 在这里我把我实现实体类的方式共享出来,大家也请指点一下。
 * 
 * 简单说一下原理:
 * 把IDataReader转成Dictionary<string, object>,然后在读取时再赋值到相应的字段属性内。
 * 而关联表通过交流Dictionary<string, object>来实现关联表操作
 * 
 * 现在头疼的地方就是getParameter()方法,用这个方法我可以把简单的添加修改删除代码抽象出来,不用每个类去专门写一段添加修改删除的操作
 * 头疼的是,修改时也需要把整个实体类的所有字段都读一遍,这明显就是浪费了。
 * 
 * 我本身预想有两种方法,一是用switch,或是If,或是干脆再来一个方法专门给修改用。但是一直没有作出选择,不知道还有什么更好的办法处理不。
 */
//实体类的基类
public abstract class RecordBase
{
    //记录IDataReader数据集内的数据
    //此处的Dictionary<>,实际应用时我用的是一个object[]数据来作记录,获取字段值时才将数组转换成Dictionary<>来使用。这样实体类才实现能序列化。
    private Dictionary<string, object> _recordValue;
    protected Dictionary<string, object> recordValue
    {
        get { if (_recordValue == null) { _recordValue = new Dictionary<string, object>(); } return _recordValue; }
        set { _recordValue = value; }
    }

    //接收IDataReader的数据
    public RecordBase(IDataReader dr)
    {
        this.recordValue = new Dictionary<string, object>(dr.FieldCount);
        for (int x = 0; x < dr.FieldCount; x++)
        {
            this.recordValue.Add(dr.GetName(x), dr.GetValue(x));
        }
    }
    //作为关联数据表
    public RecordBase(Dictionary<string, object> recordValue)
    {
        this.recordValue = recordValue;
    }

    //获取字段值,之所以作成一个方法单独处理只是不想把try放得到处都是而以。
    private object getValue(string field)
    {
        object value = null;
        /*
         * 这里之所有用try而不用recordValue.ContainsKey来判断字段是否存在,
         * 是因为字段不存在这种错误是不应该出现的,如果出现那就是查询句或是别的地方有错。
         * 所以不需要用recordValue.ContainsKey来跳出找不到字段的错误,
         * 而用try来抛出错误的话,可以更好的提示程序员出错是什么原因。
         */
        try
        {
            
            //字段值为DBNull时返回null,让getFieldValue作适当的处理。
            if (!(recordValue[field] is DBNull)) { value = recordValue[field]; }
        }
        catch (Exception e) { throw new Exception(string.Format("找不以字段{0}", name)); }
        return value;
    }

    #region 获取字段值
    //获取字段数据类型为 decimal 的字段值
    private decimal getFieldValue(ref decimal? properties, string fieldName)
    {
        if (!properties.HasValue) { properties = (decimal)(this.getValue(fieldName) ?? 0m); }
        return properties.GetValueOrDefault();
    }
    //获取字段数据类型为 string 的字段值
    protected string getFieldValue(ref string properties, string fieldName)
    {
        if (properties == null) { properties = (getValue(fieldName) ?? "").ToString(); }
        return properties;
    }
    /* 还有其它数据类型的字段提取方式这里就不作出来了,反正都差不多的 */
    #endregion
}
//实体类 添加修改删除操作 接口
public interface IRecordModify
{
    Dictionary<string, object> getParameter();//获取实体类的字段与字段值
    string getTableName();//因为Modify用的是泛型操作,所以需要获取列名的方法
    decimal Id { get; set; }//因为添加新记录时需要获取新记录的Id号
}
//Record数据表的实体类
public class Record : RecordBase, IRecordModify
{
    private decimal? _id;
    private string _name;

    public Record() { }
    public Record(IDataReader dr) : base(dr) { }
    public Record(Dictionary<string, object> recordValue) : base(recordValue) { }

    #region 字段
    public decimal Id
    {
        get { return this.getFieldValue(ref _id, FieldName.Id); }
        set { _id = value; }
    }
    public string Name
    {
        get { return this.getFieldValue(ref _name, FieldName.Name); }
    }
    #endregion

    #region 关系表
    [NonSerialized]
    private Relations _relations;
    public Relations Relations
    {
        get
        {
            if (_relations == null) { _relations = new Relations(this.recordValue); }
        }
    }
    #endregion

    //表名
    public const string TableName = "Record";
    //字段列表
    public class FieldName
    {
        public const string Id = "id";
        public const string Name = "name";
    }

    #region IRecordModify 成员

    Dictionary<string, object> IRecordModify.getParameter()
    {
        Dictionary<string, object> dList = new Dictionary<string, object>();
        dList.Add(FieldName.Id, this.Id);
        dList.Add(FieldName.Name, this.Name);
        return dList;
    }

    string IRecordModify.getTableName()
    {
        return TableName;
    }

    #endregion
}

//与数据表Record有关联的Relations数据表实体类
public class Relations : RecordBase 
{
    private decimal? _Id;

    public Relations() { }
    public Relations(IDataReader dr) : base(dr) { }
    public Relations(Dictionary<string, object> recordValue) : base(recordValue) { }

    public const string TableName = "Relations";
    public class FieldName
    {
        public const string Id = "id";
    }
}