2019-04-02

自定义简单的ORM框架

项目中的ORM(Object Relational Mapping)映射,多是一个项目构成的基础。 项目中直接操作odbc十分麻烦。

ADO.net返回的Table要映射到具体的类上面,还需要手动的编码。十分耗时。通过反射实现一个简单的ORM框架。

1. 定义ColumnAttribute,主要加在属性列上,用于标示和数据表中的列名

[AttributeUsage(AttributeTargets.Field|AttributeTargets.Property,AllowMultiple=false,Inherited=false)]

    public class ColumnAttribute:Attribute

    {

        public ColumnAttribute(string columnName)

        {

            this.Value = columnName;

        }

        public string Value { get; protected set; }

    }

2. 定义TableAtrribute,主要加在Model类上,用于标示和关联数据库表名。

[AttributeUsage(AttributeTargets.Class)]

    public class TableAtrribute:Attribute

    {

        public string Value { get; protected set; }

        public TableAtrribute(string tablename)

        {

            this.Value = tablename;

        }

    }

3.定义AttributeProcess类,获取指定类,映射的表名和列名

///

        /// DB Table Name

        ///

        ///

        ///

        public static string GetTableName(Type type)

        {

            string tableName = string.Empty;

            object[] attributes = type.GetCustomAttributes(false);

            foreach (var attr in attributes)

            {

                if(attr is TableAtrribute)

                {

                    TableAtrribute tableAtrribute = attr as TableAtrribute;

                    tableName = tableAtrribute.Value;

                }

            }

            if (string.IsNullOrEmpty(tableName))

            {

                tableName = type.Name;

            }

            //Todo

            return tableName;

        }

        ///

        /// DB Table Column Name

        ///

        ///

        ///

        public static string GetColumnName(PropertyInfo property)

        {

            string columnName = string.Empty;

            object[] attributes = property.GetCustomAttributes(false);

            foreach (var attr in attributes)

            {

                if (attr is ColumnAttribute)

                {

                    ColumnAttribute columnAttr = attr as ColumnAttribute;

                    columnName = columnAttr.Value;

                }

            }

            if(string.IsNullOrEmpty(columnName))

            {

                columnName = property.Name;

            }

            return columnName;

        }


4.具体Model类上,使用TableAttribute和ColumnAttribute进行标记

[TableAtrribute("Customer")]

    public class Customer

    {

        [Column("CustomerID")]

        public int CustomerID { get; set; }

        [Column("Email")]

        public string Email { get; set; }

        [Column("CustomerName")]

        public string CustomerName { get; set; }

    }


5.定义ADO.net操作类DBBase


///

        /// open DB Connection

        ///

        public void OpenDB()

        {

            try

            {

                switch (DbConfig.Type)

                {

                    case DbType.SqlServer:

                        {

                            dbConnection = new SqlConnection(DbConfig.DbString);

                            break;

                        }

                }

                dbConnection.Open();

            }

            catch (Exception ex)

            {

                throw ex;

            }

            finally

            {

            }

        }



///

        /// close DB Connection

        ///

        public void CloseSqlConnection()

        {

            if (dbCommand != null)

            {

                dbCommand.Dispose();

            }

            dbCommand = null;

            if (reader != null)

            {

                reader.Dispose();

            }

            reader = null;

            if (dbConnection != null && dbConnection.State == System.Data.ConnectionState.Open)

            {

                dbConnection.Close();

                dbConnection.Dispose();

            }

            dbConnection = null;

        }

        ///

        /// Execute

        ///

        ///

        ///

        ///

        public DbDataReader ExecuteReader(string sql, Dictionary parameters)

        {

            OpenDB();

            dbCommand = dbConnection.CreateCommand();

            dbCommand.CommandText = sql;

            if (parameters != null && parameters.Count() > 0)

            {

                foreach (var param in parameters)

                {

                    dbCommand.Parameters.Add(new SqlParameter(param.Key, param.Value));

                };

            }

            reader = dbCommand.ExecuteReader();

            return reader;

        }

6.实现ORM映射类

///

        ///  get result basic on sql result and reflect to Model

        ///

        ///

        ///

        ///

        public List Fetch(Sql sql)

        {

            try

            {

                List list = new List();

                var reader = this.dbBase.ExecuteReader(sql.GetSql(), sql.GetParams());

                Type type = typeof(T);

                if (type.IsPrimitive || type == typeof(string) || type == typeof(DateTime) || type.IsEnum)

                {

                    while (reader.Read())

                    {

                        if (type.IsEnum)

                        {

                            list.Add((T)Enum.ToObject(type, reader.GetValue(0)));

                        }

                        else

                        {

                            list.Add((T)Convert.ChangeType(reader.GetValue(0), type));

                        }

                    }

                }

                else

                {

                    while (reader.Read())

                    {

                        // 创建对象实例

                        T result = Activator.CreateInstance();

                      // 取得类上定义的所有属性

                        PropertyInfo[] properties = type.GetProperties();

                        foreach (PropertyInfo property in properties)

                        {

                          // 取得某个属性上附带的ColumnAttribute保存的ColumnName

                            string columnName = AttributeProcess.GetColumnName(property);

                            if (property.PropertyType.IsEnum)

                            {

                                property.SetValue(result, Enum.ToObject(property.PropertyType, reader.GetValue(reader.GetOrdinal(columnName))), null);

                            }

                            else

                            {

                             //1. 根据columnName取出reader 里面的值reader.GetValue(reader.GetOrdinal(columnName))

                               //把第一步取得的值放到result对象中对应的property属性上

                                property.SetValue(result, Convert.ChangeType(reader.GetValue(reader.GetOrdinal(columnName)), property.PropertyType));

                            }

                        }

                        list.Add(result);

                    }

                }

                return list;

            }

            catch (Exception ex)

            {

                throw ex;

            }

            finally

            {

                dbBase.CloseSqlConnection();

            }

        }

你可能感兴趣的:(2019-04-02)