内部信息缓存
在轻量级ORM内部,会产生大量的与类相关的信息,在前面的博文里面,我已经记录了如何来存储这些信息,具体请见轻量级ORM开发系列:Model类相关信息的处理一文。这些相关的信息都是在ORM第一个请求的时候根据配置文件所配置的程序集来进行反射得到的,所以在第一个请求的时候花费的时间会比较长,这里我记录我所设计的一个缓存,能够很好的解决这个问题。
为了能够返回强类型的结果,我这里使用Dictionary作为内部存储结构而不是Hashtable,当然我知道很多成熟的ORM都是使用的Hashtable,不过我只是做一个轻量级的学习型开发,简单就好。这里的返回结果采用IDictionary接口进行返回。
具体代码如下:
{
private static IDictionary<string, EntityInfo> StaticDic = null;
static EntityList()
{
StaticDic = new Dictionary<string, EntityInfo>();
}
public static void InsertEntityInfo(string type,EntityInfo Info)
{
if (StaticDic.ContainsKey(type))
{
return;
}
else
{
StaticDic.Add(type,Info);
}
}
public static IDictionary<string, EntityInfo> GetDic()
{
return StaticDic;
}
public static void InsertEntityInfo( EntityInfo Info)
{
InsertEntityInfo(Info.TypeFullName, Info);
}
public static bool IsContain(string name)
{
return StaticDic.ContainsKey(name);
}
public static void InsertEntityInfo(IEntity entity, EntityInfo Info)
{
string type = entity.GetType().FullName;
InsertEntityInfo(type,Info);
}
public static EntityInfo GetEntityInfo(string type)
{
if (StaticDic.ContainsKey(type))
{
return StaticDic[type];
}
else
{
return null;
}
}
public static EntityInfo GetEntityInfo(IEntity entity)
{
string type = entity.GetType().FullName;
return GetEntityInfo(type);
}
public static EntityInfo GetEntityInfo<T>() where T:IEntity
{
string type = typeof(T).FullName;
return GetEntityInfo(type);
}
}
如果你需要的Model类对应的信息不在这个缓存里面怎么办,我们需要对其开发一个访问门户,由他来判断决定这些事情
{
EntityInfo myentity = EntityList.GetEntityInfo(t.FullName);
if (myentity == null)
{
myentity= EntityInfoHandler.LoadEntityInfo(t);
if (myentity == null)
{
throw new DeveloperException(t.FullName+" has a problem,the fox orm can't load it,you must check if this class has a TableAttribute ");
}
}
return myentity;
}
查询数据缓存
提到ORM就不能不提hibernate, 分析hibernate源代码你可以发现,他有两级缓存,session level 和SessionFactory level 缓存,我这里为了开发学习,准备开发的只有一个类似session level 的一级缓存。
配置文件信息
作为一个ORM ,那么他就不可避免的有许多相关的配置信息,例如我们的连接字符串,表前缀,数据库访问提供者信息,Model程序集的相关信息等等
这里我们的配置信息类直接继承自ConfigBase<T>模型,具体实现请查看 抛弃ConfigurationManager , 实现面向对象读写配置文件 一文。
public class ORMConfig : Fox.Config.ConfigBase<ORMConfig>
{
private static ORMConfig _Instance = LoadConfig();
[XmlIgnore]
public static ORMConfig Instance
{
get { return _Instance; }
}
public static ORMConfig LoadConfig()
{
return new ORMConfig().Load();
}
public string Connection { get; set; }
public string DataPre { get; set; }
public string Provider { get; set; }
public string AssemblyInfo { get; set; }
public string DefaultDBName { get; set; }
[XmlIgnore]
public string[] AssemblyInfoList
{
get
{
if (StringHandler.HasValue(AssemblyInfo))
{
if (AssemblyInfo.Contains(","))
{
string[] myarray = AssemblyInfo.Split(',');
return myarray;
}
else if (AssemblyInfo.Contains(","))
{
string[] myarray = AssemblyInfo.Split(',');
return myarray;
}
else
{
string[] mystrarray=new string[1];
mystrarray[0]=AssemblyInfo;
return mystrarray;
}
}
else
return null;
}
}
}
其中Instance实现一个单例模式,至于他头上的[XmlIgnore]的用处,是一个序列化忽略标记。
下面来详细介绍一下他的成员属性
public string Connection { get; set; } //连接字符串
public string DataPre { get; set; } //数据库表前缀
public string Provider { get; set; } //数据库的提供者,通过反射获得实例,实现兼容多数据库
public string AssemblyInfo { get; set; } //Model程序集字符串,加载类的属性信息时将会用到,若Model分布在多个程序集,则用逗号分开
public string DefaultDBName { get; set; } //默认的数据库名
public string[] AssemblyInfoList 这个属性访问器实现分割多个程序集的字符串。