1. 持久對象映射文件
關于持久對象映射文件,這里就不多說了,可參考nhibernate的例子和文檔。 在nhibernate源代碼的根目錄里有一個nhibernate-mapping-2.0.xsd文檔,這個文檔是nhibernate用來對映射文件進行驗證的,我們也可以借助相關軟件用這個文檔來驗證映射文件的有效性。
2. 映射信息的讀取
通過Configuration類,可以用多種方式讀取映射信息,一些以Add開頭的方法就是用來加入映射信息的,這些方法最終將調用Add(XmlDocument doc)。
//** Configuration.cs **
private Hashtable classes = new Hashtable(); classes集合用于存放所有的持久對象映射信息, 它的Key為持久類的類型;Value為PermissionClass類的子類。
private void Add(XmlDocument doc) { try { Binder.dialect = Dialect.Dialect.GetDialect(properties); Binder.BindRoot( doc, CreateMappings()); } catch (MappingException me) { log.Error("Could not compile the mapping document", me); throw me; } // end try/catch }
AddDocument方法調用Binder的靜態方法BindRoot來綁定持久類映射信息。CreateMappings返回一個Mappings對象,此對象是一個簡單封裝了所有映射信息集合的類。
3. 建立對象映射信息
Binder類的BindRoot用于綁定映射信息中的所有映射內容。
//** Binder.cs **
public static void BindRoot(XmlDocument doc, Mappings model) { // ...
foreach(XmlNode n in hmNode.SelectNodes(nsPrefix + ":class", nsmgr) ) { RootClass rootclass = new RootClass(); Binder.BindRootClass(n, rootclass, model); model.AddClass(rootclass); }
// ... }
遍歷所有的類映射節點,然后調用BindRootClass來綁定類映射信息,最后將類映射信息加到集合中。 其中RootClass為PermissionClass的子類。
public static void BindRootClass(XmlNode node, RootClass model, Mappings mappings) { BindClass(node, model, mappings);
//TABLENAME XmlAttribute tableNameNode = node.Attributes["table"]; string tableName = (tableNameNode==null) ? StringHelper.Unqualify( model.PersistentClazz.Name ) : tableNameNode.Value;
XmlAttribute schemaNode = node.Attributes["schema"]; string schema = schemaNode==null ? mappings.SchemaName : schemaNode.Value; Table table = mappings.AddTable(schema, tableName); model.Table = table;
// ...
PropertiesFromXML(node, model, mappings); }
BindRootClass首先調用BindClass綁定持久類映射信息,然后調用PropertiesFromXML來綁定類屬性。
public static void BindClass(XmlNode node, PersistentClass model, Mappings mapping) { string className = node.Attributes["name"] == null ? null : node.Attributes["name"].Value; // class try { model.PersistentClazz = ReflectHelper.ClassForName(className); } catch ( Exception cnfe ) { throw new MappingException( "persistent class not found", cnfe); }
// ... }
BindClass通過反射來取得持久對象的類型。
protected static void PropertiesFromXML(XmlNode node, PersistentClass model, Mappings mappings) { string path = model.Name; Table table = model.Table;
foreach(XmlNode subnode in node.ChildNodes) { CollectionType collectType = CollectionType.CollectionTypeFromString(name); Value value = null; if (collectType!=null) { value = new Value(table); BindValue(subnode, value, true); } else if ( "many-to-one".Equals(name) ) { value = new ManyToOne(table); BindManyToOne(subnode, (ManyToOne) value, propertyName, true); } else if ( "any".Equals(name) ) { value = new Any(table); BindAny(subnode, (Any) value, true); } else if ( "one-to-one".Equals(name) ) { value = new OneToOne(table, model.Identifier ); BindOneToOne(subnode, (OneToOne) value, true); } else if ( "property".Equals(name) ) { value = new Value(table); BindValue(subnode, value, true, propertyName); } else if ( "component".Equals(name) ) { value = new Component(model); BindComponent(subnode, (Component) value, reflectedClass, subpath, true, mappings); } else if ( "subclass".Equals(name) ) { Subclass subclass = new Subclass(model); BindSubclass( subnode, subclass, mappings ); } else if ( "joined-subclass".Equals(name) ) { Subclass subclass = new Subclass(model); BindJoinedSubclass( subnode, subclass, mappings); } if ( value!=null) { Property prop = new Property(value); BindProperty(subnode, prop, mappings); } } }
遍歷所有子節點,然后根據節點類型對進行綁定。(注: 部分內容已刪除) 關于屬性的映射以后有空再詳細研究,只需要知道屬性已加入到RootClass的Properties屬性就行了。
|