ORM映射框架总结--实体分析器

1.      
什么是数据分析器

前面一篇文章讲到过数据分析器,什么是数据分析器。其实很容易理解,就是对数据进行分析采集的一个工具,说白了就是一个小程序,在本ORM框架中对实体对象进行必要的数据分析,获得实体对象的各种信息缓存,以便在后续的工作中直接提取数据。这个是相对去年写的那个ORM有所改进的,在缓存实体信息的时候,在一定程度上可以提高该框架的性能

2.      
实体分析器的原理简单介绍

简单的UML图:

图总是能给人最直观的感觉。从上面的图我们可以看出,这个分析器分为了几个过程:

(1)      
读取实体信息

以上实体都是通过上篇介绍过的特性来描述的,他们定义了数据库和实体之间关系的代理桥梁。读取该些实体的信息,包括实体的描述的四个特性,实体的定义的变量,实体的属性等信息。

(2)      
缓存实体信息

此个步骤是紧接上面一步的,可以看出将实体信息分析之后将信息缓存。多个实体信息,我们采用键值方式来存储。而这个缓存也是一个全局的缓存,因为这些信息在全局程序中共享,而非某个模块独享

(3)      
使用信息

为什么读取缓存这些信息,必然是它有可用之处。数据读取肯定是用来使用的。这当然是废话。某个模块需要实体信息数据,就不必要去每次在分析这些数据,直接从缓存中读取

3.      
实体的定义

在这个过程中我们定义数据库描述的代理实体是有特定规律的,而不是我们随随便便定义的一个实体对象。因为这些实体有着特殊的含义,所以相当于普通的实体来说这些还是有着重大意义的。

 

从上图可以看出,在这个ORM中定义了一个公共接口IEntity,该接口有一个实现类BaseEntity。没有定义任何方法,IEntity但是继承了另外一个接口IDisposable。看到这大家应该都知道为什么这样定义了。而BaseEntity实现了接口IEntity并实现了Dispose()方法。

 IEntity源码

代码

 1 /**
 2  * 2010-1-28
 3  * 
 4  * 情 缘
 5  * 
 6  * 所有实体模型的父类接口。
 7  * 
 8  * 该接口通过继承接口 IDisposable 可以实现自动实现
 9  * 垃圾回收的效果。实体的调用Dispose() 方法来手动
10  * 释放占用的内存,同时也可以使用using 关键字来控
11  * 制实体的作用域范围,并及时释放内存
12  * 
13  * */
14 
15 using System;
16 
17 namespace CommonData.Entity
18 {
19 
20     /// <summary>
21     /// 公共实体基类的公共接口,用于释放对象分配空间
22     /// </summary>
23     public interface IEntity:IDisposable
24     {
25     }
26 }
27 

BaseEntity 源码

 代码

/**
 * 2010-1-28
 * 
 * 情 缘
 * 
 * 这个实体类是所有实体模型类的父类,该实体类实现了
 * IEntity 接口,实现了手动释放内存方法。该实体类使
 * 用特性 Serializable修饰,说明该实体类要被序列化。
 * 而实体类使用abstract 关键字修饰,说明该类的实例
 * 不能通过自身来实例化,必须通过该实体类的子类来实
 * 现。使用该种模式,保证了设计在总体上的结构性
 * 
 * */

using System;

namespace CommonData.Entity
{
    [Serializable]
    public abstract class BaseEntity:IEntity
    {
        /// <summary>
        /// 隐式实现接口方法,用于释放内存
        /// </summary>
        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }
    }
}

普通实体源码

代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonData.Entity;
using CommonData.Model.Core;

namespace Office.Entity
{
    [Serializable]
    [TableAttribute(DBName = "OA_DB", Name = "TabUser", PrimaryKeyName = "Id", IsInternal = false)]
    public class TabUser : BaseEntity
    {
        public TabUser()
        {
        }

        private int id;
        [ColumnAttribute(Name = "Id", IsPrimaryKey = true, AutoIncrement = true, DataType = DataType.Int, CanNull = false)]
        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        private string userName;
        [ColumnAttribute(Name = "UserName", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Nvarchar, CanNull = false)]
        public string UserName
        {
            get { return userName; }
            set { userName = value; }
        }

        private string passWord;
        [ColumnAttribute(Name = "PassWord", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Nvarchar, CanNull = false)]
        public string PassWord
        {
            get { return passWord; }
            set { passWord = value; }
        }

        private int sex;
        [ColumnAttribute(Name = "Sex", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Int, CanNull = false)]
        public int Sex
        {
            get { return sex; }
            set { sex = value; }
        }

        private DateTime birthday;
        [ColumnAttribute(Name = "Birthday", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Datetime, CanNull = false)]
        public DateTime Birthday
        {
            get { return birthday; }
            set { birthday = value; }
        }

        private string cardID;
        [ColumnAttribute(Name = "CardID", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Varchar, CanNull = true)]
        public string CardID
        {
            get { return cardID; }
            set { cardID = value; }
        }

        private int age;
        [ColumnAttribute(Name = "Age", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Int, CanNull = true)]
        public int Age
        {
            get { return age; }
            set { age = value; }
        }

        private string address;
        [ColumnAttribute(Name = "Address", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Nvarchar, CanNull = true)]
        public string Address
        {
            get { return address; }
            set { address = value; }
        }

        private int isMarried;
        [ColumnAttribute(Name = "IsMarried", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Int, CanNull = true)]
        public int IsMarried
        {
            get { return isMarried; }
            set { isMarried = value; }
        }

        private int roleId;
        [ColumnAttribute(Name = "RoleId", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Int, CanNull = false)]
        public int RoleId
        {
            get { return roleId; }
            set { roleId = value; }
        }

        private int iSFobid;
        [ColumnAttribute(Name = "ISFobid", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Int, CanNull = false)]
        public int ISFobid
        {
            get { return iSFobid; }
            set { iSFobid = value; }
        }

        private string descript;
        [ColumnAttribute(Name = "Descript", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Nvarchar, CanNull = true)]
        public string Descript
        {
            get { return descript; }
            set { descript = value; }
        }

        private string remark;
        [ColumnAttribute(Name = "Remark", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Nvarchar, CanNull = true)]
        public string Remark
        {
            get { return remark; }
            set { remark = value; }
        }

        private string ext1;
        [ColumnAttribute(Name = "Ext1", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Nvarchar, CanNull = true)]
        public string Ext1
        {
            get { return ext1; }
            set { ext1 = value; }
        }

        private string ext2;
        [ColumnAttribute(Name = "Ext2", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Nvarchar, CanNull = true)]
        public string Ext2
        {
            get { return ext2; }
            set { ext2 = value; }
        }

        private string ext3;
        [ColumnAttribute(Name = "Ext3", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Nvarchar, CanNull = true)]
        public string Ext3
        {
            get { return ext3; }
            set { ext3 = value; }
        }

        private string ext4;
        [ColumnAttribute(Name = "Ext4", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Nvarchar, CanNull = true)]
        public string Ext4
        {
            get { return ext4; }
            set { ext4 = value; }
        }

        private string ext5;
        [ColumnAttribute(Name = "Ext5", IsPrimaryKey = false, AutoIncrement = false, DataType = DataType.Nvarchar, CanNull = true)]
        public string Ext5
        {
            get { return ext5; }
            set { ext5 = value; }
        }

    }
}

这里的实体比之前我们一般写的实体对象复杂多了,有了很多其他的属性描述。我们实现起来编写这些文件很麻烦,这里我们自然想到了代码生成器,对就是代码生成器。Codesimth 是一个可以自定义模板的代码生成器,我们可以很容易的实现这些代码的生成。这里我自己也写了一个针对于这个实体生成的代码生成器,前面有相关文章介绍过,有兴趣可以阅读一下。

4.      
实体信息的读取

上面说到过实体信息的读取其实方法很简单,就是使用反射机制去读取实现属性方法,特性等信息。反射在于很多编程人员来说都是一件非常具有挑战性而且神秘的工作,有时候听到这两个字就望而生畏,其实不然,只要掌握了规律,理解了原理就可以了。无论是C#还是Java 原理都是一样的。但是反射是作为一个程序高手通往高境界的必经之路。所以掌握反射来说是对编程发展是很有好处的。

下面是实体信息读取源码抽象类

代码

/**
 * 2010-2-1
 * 
 * 情 缘
 * 
 * 该类是一个抽象类,定义了一些获得表实体信息的方法。
 * 该类定义为抽象类,其所有的方法也是抽象方法。也就
 * 是说该类的所有方法都需要由其子类去实现。
 * 
 * */
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CommonData.Model.Core;
using System.Reflection;

namespace CommonData.Entity
{
    public abstract class BaseEntityAbstract
    {
        /// <summary>
        /// 根据实体的类型获得实体表信息
        /// </summary>
        /// <param name="type">实体类类型</param>
        /// <returns></returns>
        public abstract TableInfo GetTableInfo(Type type);

        /// <summary>
        /// 根据实体类的公共接口获得实体表信息
        /// </summary>
        /// <param name="entity">实体公共接口</param>
        /// <returns></returns>
        public abstract TableInfo GetTableInfo(IEntity entity);

        /// <summary>
        /// 根据实体泛型类型获得实体表信息
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <returns></returns>
        public abstract TableInfo GetTableInfo<T>() where T:IEntity;

        /// <summary>
        /// 根据实体的类型获得实体表列信息
        /// </summary>
        /// <param name="type">实体类类型</param>
        /// <returns></returns>
        public abstract ColumnAttribute[] GetColumnAttribute(Type type);

        /// <summary>
        /// 根据实体类的公共接口获得实体表列信息
        /// </summary>
        /// <param name="entity">实体公共接口</param>
        /// <returns></returns>
        public abstract ColumnAttribute[] GetColumnAttribute(IEntity entity);

        /// <summary>
        /// 根据实体泛型类型获得实体表列信息
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <returns></returns>
        public abstract ColumnAttribute[] GetColumnAttribute<T>() where T : IEntity;

        /// <summary>
        /// 根据实体的类型获得实体字段信息
        /// </summary>
        /// <param name="type">实体类类型</param>
        /// <returns></returns>
        public abstract FieldInfo[] GetFieldInfo(Type type);

        /// <summary>
        /// 根据实体类的公共接口获得实体字段信息
        /// </summary>
        /// <param name="entity">实体公共接口</param>
        /// <returns></returns>
        public abstract FieldInfo[] GetFieldInfo(IEntity entity);

        /// <summary>
        /// 根据实体泛型类型获得实体字段信息
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <returns></returns>
        public abstract FieldInfo[] GetFieldInfo<T>() where T : IEntity;

        /// <summary>
        /// 根据实体的类型获得实体属性信息
        /// </summary>
        /// <param name="type">实体类类型</param>
        /// <returns></returns>
        public abstract PropertyInfo[] GetPropertyInfo(Type type);

        /// <summary>
        /// 根据实体类的公共接口获得实体属性信息
        /// </summary>
        /// <param name="entity">实体公共接口</param>
        /// <returns></returns>
        public abstract PropertyInfo[] GetPropertyInfo(IEntity entity);

        /// <summary>
        /// 根据实体泛型类型获得实体属性信息
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <returns></returns>
        public abstract PropertyInfo[] GetPropertyInfo<T>() where T:IEntity;

        /// <summary>
        /// 根据实体的类型获得实体字段属性信息
        /// </summary>
        /// <param name="type">实体类类型</param>
        /// <returns></returns>
        public abstract LinkTableAttribute[] GetLinkTableAttribute(Type type);

        /// <summary>
        /// 根据实体类的公共接口获得实体字段属性信息
        /// </summary>
        /// <param name="entity">实体公共接口</param>
        /// <returns></returns>
        public abstract LinkTableAttribute[] GetLinkTableAttribute(IEntity entity);

        /// <summary>
        /// 根据实体泛型类型获得实体字段属性信息
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <returns></returns>
        public abstract LinkTableAttribute[] GetLinkTableAttribute<T>() where T:IEntity;

        /// <summary>
        /// 根据实体的类型获得实体字段集合属性信息
        /// </summary>
        /// <param name="type">实体类类型</param>
        /// <returns></returns>
        public abstract LinkTablesAttribute[] GetLinkTablesAttribute(Type type);

        /// <summary>
        /// 根据实体类的公共接口获得实体字段集合属性信息
        /// </summary>
        /// <param name="entity">实体公共接口</param>
        /// <returns></returns>
        public abstract LinkTablesAttribute[] GetLinkTablesAttribute(IEntity entity);

        /// <summary>
        /// 根据实体的类型获得实体字段集合属性信息
        /// </summary>
        /// <typeparam name="T">泛型类型</typeparam>
        /// <returns></returns>
        public abstract LinkTablesAttribute[] GetLinkTablesAttribute<T>() where T:IEntity;
    }
}

该抽象类定义了各种方式获得实体性的方式。而且有很多都是使用的重载方式,这样更能体现程序结构的灵活性,健壮性。这个过程中不乏使用了泛型,以及泛型约束,使用泛型约束很大程度上使得这个程序的针对的工作性质比较强,将实体分析约束到了某个特定的范围之内,这样可以省去很多不必要的麻烦

获得实体的信息代码

代码

/// <summary>
        /// 根据实体的类型获得实体表信息
        /// </summary>
        /// <param name="type">实体类类型</param>
        /// <returns></returns>
        public override TableInfo GetTableInfo(Type type)
        {
            TableInfo tableInfo = EntityTypeCache.GetTableInfo(type);
            if (tableInfo == null)
            {
                tableInfo = new TableInfo();
                TableAttribute[] tableAttribute = type.GetCustomAttributes(typeof(TableAttribute),false) as TableAttribute[];
                
                PropertyInfo[] properties = type.GetProperties();
                foreach (PropertyInfo property in properties)
                {
                    tableInfo.DicProperties.Add(property.Name,property);
                    if (property.GetCustomAttributes(typeof(ColumnAttribute), false).Length == LENGTH)
                    {
                        tableInfo.DicColumns.Add(property.Name, property.GetCustomAttributes(typeof(ColumnAttribute), false)[0] as ColumnAttribute);
                    }
                    if (property.GetCustomAttributes(typeof(LinkTableAttribute), false).Length == LENGTH)
                    {
                        tableInfo.DicLinkTable.Add(property.Name,property.GetCustomAttributes(typeof(LinkTableAttribute),false)[0] as LinkTableAttribute);
                    }
                    if (property.GetCustomAttributes(typeof(LinkTablesAttribute), false).Length == LENGTH)
                    {
                        tableInfo.DicLinkTables.Add(property.Name, property.GetCustomAttributes(typeof(LinkTablesAttribute), false)[0] as LinkTablesAttribute);
                    }
                }
                FieldInfo[] fields = type.GetFields();
                foreach (FieldInfo field in fields)
                {
                    tableInfo.DicFields.Add(field.Name,field);
                }
                
                if (tableAttribute.Length == LENGTH)
                {
                    tableInfo.Table = tableAttribute[0];
                }
                else
                {
                    throw new Exception("一个实体类上不能有相同的特性");
                }
                tableInfo.Columns = tableInfo.DicColumns.Values.ToArray();
                tableInfo.Fields = tableInfo.DicFields.Values.ToArray();
                tableInfo.LinkTable = tableInfo.DicLinkTable.Values.ToArray();
                tableInfo.LinkTables = tableInfo.DicLinkTables.Values.ToArray();
                tableInfo.Properties = tableInfo.DicProperties.Values.ToArray();
                EntityTypeCache.InsertTableInfo(type,tableInfo);
            }
            return tableInfo;
        }

5.      
缓存机制

其实这个这个缓存机制很简单的,我们经常想到的缓存机制就是Session ,Application,ViewState 等对象。这些都是web程序中的缓存对象,但是如果这些运用在控制台程序或者WinForm程序中呢,这些对象显然作用不大。于是我们需要一个能够公用的缓存机制。

有些人一直使用static 类,static 方法,他们喜欢对这种方式百用不怠,因为他们感觉static 就是爽。深入的想一下,为什么要这样使用,因为这些东西是在程序加载的时候就缓存起来了。于是我们可以在这个方面下功夫来实现我们的缓存

定义的缓存类:

代码

/**
 * 2010-1-30
 * 
 * 情 缘
 * 
 * 该类构建了一个内存缓存器,这个缓存器缓存了数据库
 * 对应实体类的特性信息,字段和属性。这些信息在程序
 * 加载或第一次使用的时候缓存到这个存储其中来。以后
 * 再吃读取这些信息的时候不需要重新去加载这些信息,
 * 直接从内存中读取即可
 * 
 * */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CommonData.Entity
{
    public static class EntityTypeCache
    {
        //表实体信息存储器,用于存储表实体信息
        private static IDictionary<Type, TableInfo> cache = null;

        /// <summary>
        /// 静态构造方法
        /// 使用静态构造方法,确保该构造方法只执行一次,不会还原初始化值
        /// 因为数据不会丢失,而且是一直保存在内存中,这样就达到了一个
        /// 临时存储器的功能
        /// </summary>
        static EntityTypeCache()
        {
            cache = new Dictionary<Type, TableInfo>();
        }

        /// <summary>
        /// 将表实体信息缓存到临时存储器中
        /// </summary>
        /// <param name="type">实体的类型</param>
        /// <param name="tableInfo">表实体信息</param>
        public static void InsertTableInfo(Type type,TableInfo tableInfo)
        {
            if (cache.ContainsKey(type))
            {
                return;
            }
            else 
            {
                cache.Add(type,tableInfo);
            }
        }

        /// <summary>
        /// 将表实体信息缓存到临时存储器中
        /// </summary>
        /// <param name="entity">实体公共接口</param>
        /// <param name="tableInfo">表实体信息</param>
        public static void InsertTableInfo(IEntity entity, TableInfo tableInfo)
        {
            Type type = entity.GetType();
            InsertTableInfo(type,tableInfo);
        }

        /// <summary>
        /// 根据实体类的类型获得表特性信息
        /// </summary>
        /// <param name="type">实体类的类型</param>
        /// <returns></returns>
        public static TableInfo GetTableInfo(Type type)
        {
            if (cache.ContainsKey(type))
            {
                return cache[type];
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 根据实体公共接口获得表特性信息
        /// </summary>
        /// <param name="entity">实体公共接口</param>
        /// <returns></returns>
        public static TableInfo GetTableInfo(IEntity entity)
        {
            Type type = entity.GetType();
            return GetTableInfo(type);
        }

        /// <summary>
        /// 根据泛型类型获得表实体信息
        /// </summary>
        /// <typeparam name="T">泛型类</typeparam>
        /// <returns></returns>
        public static TableInfo GetTableInfo<T>() where T:IEntity
        {
            Type type = typeof(T);
            return GetTableInfo(type);
        }
    }
}

使用静态构造方法,确保该构造方法只执行一次,不会还原初始化值,因为数据不会丢失,而且是一直保存在内存中,这样就达到了一个临时存储器的功能。

这里和上面读取实体信息是一起使用的,每次读取实体信息的时候就从缓存中读取,如果缓存中没有这些数据,就重新使用实体分析器去读取这些数据

6.      
测试分析

(1).数据读取分析

 测试代码

代码

BaseEntityAbstract cache = new BaseEntityHelper();
cache.GetTableInfo(typeof(TabUser));
foreach (PropertyInfo fi in cache.GetTableInfo(typeof(TabUser)).Properties)
{
                    Console.WriteLine(fi.Name);
}

 测试结果:

 

从上面的代码中可以看到从缓存中获取了实体的相应信息。 cache.GetTableInfo(typeof(TabUser)) 这句代码是有特定信息的,我们可以使用这个方法来在程序启动的时候注册所有实体的信息

     (2).缓存性能分析

测试代码

代码

static void Main(string[] args)
        {

            BaseEntityAbstract cache = new BaseEntityHelper();
            cache.GetTableInfo(typeof(TabUser));
            Console.WriteLine();
            Console.WriteLine("BeginTime: " + DateTime.Now.Millisecond);
            for (int i = 0; i < 10000; i++)
            {
                foreach (PropertyInfo fi in typeof(TabUser).GetProperties())
                {
                    //Console.WriteLine(fi.Name);
                }
            }
            Console.WriteLine("BeginTime: " + DateTime.Now.Millisecond);
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("BeginTime: " + DateTime.Now.Millisecond);
            for (int i = 0; i < 10000; i++)
            {
                foreach (PropertyInfo fi in cache.GetTableInfo(typeof(TabUser)).Properties)
                {
                    //Console.WriteLine(fi.Name);
                }
            }
            Console.WriteLine("BeginTime: " + DateTime.Now.Millisecond);
        }

 

以上我们分别用反射获取实体信息,和在缓存中获取实体信息,然后分别循环10000次。我们看看他们的所用的时间比较

 

 看看上面的图,我们就之后了性能的高低,这里说明一个道理这个缓存器起到了作用。这也达到了先前的目的。

 (注: ORM涉及内容比较多,后续期待,有兴趣的可以与本人探讨) 

 

 

时间: 2024-10-01 14:27:41

ORM映射框架总结--实体分析器的相关文章

ORM映射框架总结--数据库操作库(精修版)

1.       ORM数据库操作原理 前面已经介绍过了个人ORM映射框架中的三个核心库: 实体-数据库 映射特性关系: http://www.cnblogs.com/qingyuan/archive/2010/04/02/1702998.html 实体分析器: http://www.cnblogs.com/qingyuan/archive/2010/04/05/1704546.html Sql 语句生成组建: http://www.cnblogs.com/qingyuan/archive/20

ORM映射框架总结--映射桥梁

1.       感言 写博客之前先自我吹嘘一下,给这些文章来些自我介绍. 半年前自己借用了5个多月的业务时间写了一个个人ORM映射框架.在之前的博 客中也有过写过该框架的相关介绍.半年前的那个ORM只不过是自己想象的关系映射的一个雏形,那一段曾经让自己骄傲过得代码的确存在着太多的问题,但是我始终没有放弃过对它的修改.又过了半年,这个ORM映射框架在之前的基础上有了很大的改进.在此与大家分享一下,希望大家共同探讨,共同学习.   2.       框架整体介绍 说道这里,其实这个ORM框架仍然存

ORM映射框架总结--代码生成器

年前发布了一些文章,是关于.NET数据操作(点击查看)的.刚开始学习编程的时候,总感觉Java中的Hibernate 功能好强大,现在也不可否认它的确强大,特别是它在数据关系处理上,却是那样的让人称叹.          当我那时还不知道.net 中的Linq的时候,一直想自己能够简单的写个ORM映射框架.去年花费了几个月的业务时间终于算是整出来了,一些基本操作都能够实现了,自己号称从数据库操作冗余代码中解脱出来,其实自己很天真,那个框架是多么的不完善.总结了一下,最近超体力透支的准备将其扩展,

ORM映射框架总结--数据操作(一)

  ORM(对象关系映射) ,在我们印象中Hibernate是体现的比较明显的.因为它的轻量级和低入侵式,得到很多IT人士的亲睐. 正是因为ORM 这种映射关系,使程序各个模块之间的耦合度大大降低,使得程序灵活多变..NET 在Linq 出现之前几乎没有看到什么ORM映射框架,今年自己也.net 方面下了一番苦功夫学习,有小小成果就是自己写了一个ORM映射框架.在2009年的最后一天与大家分享   程序总体设计思路:   姑且用上面的图来表示整个框架的流程.其实就是用一些特性来描述实体和数据库之

ORM映射框架总结--SQL 语句生成组件

 1.       SQL 语句生成组建 之前说过ORM框架中有一个非常重要的组件,那就是SQL语句生成组件.SQL语句生成组件,顾名思义就是用于生成sql语句的一个组件.之前的Attribute 是用于修饰实体信息,而上一章讲的实体分析器分析了实体信息,在很大一部分程度上,以上做工作就是为这个SQL语句生成组件服务的. 该组件的核心接口是IDbFactory,它实现了接口IDisposable 目前该ORM支持SQL Server 数据库的sql语句生成,在后期过程中会逐步实现对Oracle,

ODB——基于c++的ORM映射框架尝试(安装)

这篇博客应该是和之前的重拾cgi一起的.当时为了模仿java的web框架,从页面的模板,到数据库的ORM,都找个对应的库来进行尝试.数据库用的就是ODB,官方网站是http://www.codesynthesis.com/products/odb/. 1.安装 odb是直接提供源代码的,主要包含这几个部分:odb.libodb.libodb-sqlite等,用途分别是: odb是ODB编译器,类似于qt的moc,将c++源码中包含ODB特定宏的代码,生成对应的c++代码. libodb是运行时库

ORM映射框架总结--日志处理

在我们做项目的过程中,日志跟踪异常是非常必要的,当程序发布到服务器上时,如果出现异常直接抛出给用户这是非常不友好的.对于不懂程序的用户来说,这回让人感觉莫名其妙,对于那些程序高手,可能就是攻破这个网站的关键.   在asp.net 程序的web.config 配置文件中有如下两个节点作为程序异常配置: (1)<customErrors>节点 <customErrors>节点用于定义 一些自定义错误信息的信息.此节点有Mode和defaultRedirect两个属性,其中 defau

ORM映射框架总结--数据操作(二)

  1.TableInfo 封装实体特性类 代码  1 /** 2  *  3  * 2009-4-11 4  *  5  *  6  * 表实体的特性信息 7  * */ 8 using System; 9 using System.Collections.Generic;10 using System.Linq;11 using System.Text;12 using System.Reflection;13 14 namespace CommonData.Model15 {16     

ORM映射框架总结--数据操作(七)

2. 数据库操作实现类 SqlHelper 代码 /** *  * 2009-4-22 *  *  * 数据库操作的公共类 * */using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Reflection;using System.Data;using System.Data.SqlClient;using CommonData.Model; namespac