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属性就行了。
