classbinder.cs
来自「NHibernate NET开发者所需的」· CS 代码 · 共 1,196 行 · 第 1/3 页
CS
1,196 行
{
if (subnode.Attributes["class"] == null)
throw new MappingException("no class given for generator");
model.IdentifierGeneratorStrategy = subnode.Attributes["class"].Value;
Dictionary<string, string> parms = new Dictionary<string, string>();
// NOTE: While fixing NH-1061, a couple of lines similar to the following
// were added to ClassIdBinder.GetGeneratorProperties(). It looks like
// we may need it here too. But I don't want to put it in just yet.
/* if (model.Table.Schema != null)
parms.Add("schema", model.Table.Schema);
else */
if (mappings.SchemaName != null)
parms.Add(Id.PersistentIdGeneratorParmsNames.Schema, dialect.QuoteForSchemaName(mappings.SchemaName));
foreach (XmlNode childNode in subnode.SelectNodes(HbmConstants.nsParam, namespaceManager))
parms.Add(
childNode.Attributes["name"].Value,
childNode.InnerText
);
model.IdentifierGeneratorProperties = parms;
}
model.Table.SetIdentifierValue(model);
//unsaved-value
XmlAttribute nullValueNode = node.Attributes["unsaved-value"];
if (nullValueNode != null)
model.NullValue = nullValueNode.Value;
else if (model.IdentifierGeneratorStrategy == "assigned")
// TODO: H3 has model.setNullValue("undefined") here, but
// NH doesn't (yet) allow "undefined" for id unsaved-value,
// so we use "null" here
model.NullValue = "null";
else
model.NullValue = null;
}
protected void BindComponent(XmlNode node, Component model, System.Type reflectedClass,
string className, string path, bool isNullable)
{
XmlAttribute classNode = node.Attributes["class"];
if ("dynamic-component".Equals(node.Name))
{
model.IsEmbedded = false;
model.IsDynamic = true;
}
else if (classNode != null)
{
model.ComponentClass = ClassForNameChecked(
classNode.Value, mappings,
"component class not found: {0}");
model.ComponentClassName = FullClassName(classNode.Value, mappings);
model.IsEmbedded = false;
}
else if (reflectedClass != null)
{
model.ComponentClass = reflectedClass;
model.IsEmbedded = false;
}
else
{
// an "embedded" component (ids only)
model.ComponentClass = model.Owner.MappedClass;
model.IsEmbedded = true;
}
foreach (XmlNode subnode in node.ChildNodes)
{
//I am only concerned with elements that are from the nhibernate namespace
if (subnode.NamespaceURI != Configuration.MappingSchemaXMLNS)
continue;
string name = subnode.LocalName; //.Name;
string propertyName = GetPropertyName(subnode);
string subpath = propertyName == null ? null : StringHelper.Qualify(path, propertyName);
IValue value = null;
CollectionBinder binder = new CollectionBinder(this);
if (binder.CanCreate(name))
{
Mapping.Collection collection = binder.Create(name, subnode, className,
subpath, model.Owner, model.ComponentClass);
mappings.AddCollection(collection);
value = collection;
}
else if ("many-to-one".Equals(name) || "key-many-to-one".Equals(name))
{
value = new ManyToOne(model.Table);
BindManyToOne(subnode, (ManyToOne) value, subpath, isNullable);
}
else if ("one-to-one".Equals(name))
{
value = new OneToOne(model.Table, model.Owner);
BindOneToOne(subnode, (OneToOne) value);
}
else if ("any".Equals(name))
{
value = new Any(model.Table);
BindAny(subnode, (Any) value, isNullable);
}
else if ("property".Equals(name) || "key-property".Equals(name))
{
value = new SimpleValue(model.Table);
BindSimpleValue(subnode, (SimpleValue) value, isNullable, subpath);
}
else if ("component".Equals(name) || "dynamic-component".Equals(name) || "nested-composite-element".Equals(name))
{
System.Type subreflectedClass = model.ComponentClass == null
?
null
:
GetPropertyType(subnode, model.ComponentClass, propertyName);
value = new Component(model);
BindComponent(subnode, (Component) value, subreflectedClass, className, subpath, isNullable);
}
else if ("parent".Equals(name))
model.ParentProperty = propertyName;
if (value != null)
model.AddProperty(CreateProperty(value, propertyName, model.ComponentClass, subnode));
}
}
protected Mapping.Property CreateProperty(IValue value, string propertyName, System.Type parentClass,
XmlNode subnode)
{
if (parentClass != null && value.IsSimpleValue)
value.SetTypeUsingReflection(parentClass.AssemblyQualifiedName, propertyName, PropertyAccess(subnode));
// This is done here 'cos we might only know the type here (ugly!)
if (value is ToOne)
{
ToOne toOne = (ToOne) value;
string propertyRef = toOne.ReferencedPropertyName;
if (propertyRef != null)
mappings.AddUniquePropertyReference(toOne.ReferencedEntityName, propertyRef);
}
value.CreateForeignKey();
Mapping.Property prop = new Mapping.Property();
prop.Value = value;
BindProperty(subnode, prop);
return prop;
}
protected void BindProperty(XmlNode node, Mapping.Property property)
{
string propName = XmlHelper.GetAttributeValue(node, "name");
property.Name = propName;
//IType type = property.Value.Type;
//if (type == null)
// throw new MappingException("could not determine a property type for: " + property.Name);
property.PropertyAccessorName = PropertyAccess(node);
XmlAttribute cascadeNode = node.Attributes["cascade"];
property.Cascade = (cascadeNode == null) ? mappings.DefaultCascade : cascadeNode.Value;
XmlAttribute updateNode = node.Attributes["update"];
property.IsUpdateable = (updateNode == null) ? true : "true".Equals(updateNode.Value);
XmlAttribute insertNode = node.Attributes["insert"];
property.IsInsertable = (insertNode == null) ? true : "true".Equals(insertNode.Value);
XmlAttribute optimisticLockNode = node.Attributes["optimistic-lock"];
property.IsOptimisticLocked = (optimisticLockNode == null) ? true : "true".Equals(optimisticLockNode.Value);
XmlAttribute generatedNode = node.Attributes["generated"];
string generationName = generatedNode == null ? null : generatedNode.Value;
PropertyGeneration generation = ParsePropertyGeneration(generationName);
property.Generation = generation;
if (generation == PropertyGeneration.Always || generation == PropertyGeneration.Insert)
{
// generated properties can *never* be insertable...
if (property.IsInsertable)
if (insertNode == null)
// insertable simply because that is the user did not specify
// anything; just override it
property.IsInsertable = false;
else
// the user specifically supplied insert="true",
// which constitutes an illegal combo
throw new MappingException(
"cannot specify both insert=\"true\" and generated=\"" + generationName +
"\" for property: " + propName);
// properties generated on update can never be updateable...
if (property.IsUpdateable && generation == PropertyGeneration.Always)
if (updateNode == null)
// updateable only because the user did not specify
// anything; just override it
property.IsUpdateable = false;
else
// the user specifically supplied update="true",
// which constitutes an illegal combo
throw new MappingException(
"cannot specify both update=\"true\" and generated=\"" + generationName +
"\" for property: " + propName);
}
if (log.IsDebugEnabled)
{
string msg = "Mapped property: " + property.Name;
string columns = Columns(property.Value);
if (columns.Length > 0)
msg += " -> " + columns;
if (property.Type != null)
msg += ", type: " + property.Type.Name;
log.Debug(msg);
}
property.MetaAttributes = GetMetas(node);
}
protected static PropertyGeneration ParsePropertyGeneration(string name)
{
switch (name)
{
case "insert":
return PropertyGeneration.Insert;
case "always":
return PropertyGeneration.Always;
default:
return PropertyGeneration.Never;
}
}
protected static string Columns(IValue val)
{
StringBuilder columns = new StringBuilder();
bool first = true;
foreach (ISelectable col in val.ColumnIterator)
{
if (first)
first = false;
else
columns.Append(", ");
columns.Append(col.Text);
}
return columns.ToString();
}
//automatically makes a column with the default name if none is specified by XML
protected void BindSimpleValue(XmlNode node, SimpleValue model, bool isNullable, string path)
{
BindSimpleValueType(node, model);
BindColumnsOrFormula(node, model, path, isNullable);
XmlAttribute fkNode = node.Attributes["foreign-key"];
if (fkNode != null)
model.ForeignKeyName = fkNode.Value;
}
private void BindSimpleValueType(XmlNode node, SimpleValue simpleValue)
{
string typeName = null;
Dictionary<string, string> parameters = new Dictionary<string, string>();
XmlAttribute typeNode = node.Attributes["type"];
if (typeNode == null)
typeNode = node.Attributes["id-type"]; //for an any
if (typeNode != null)
typeName = typeNode.Value;
XmlNode typeChild = node.SelectSingleNode(HbmConstants.nsType, namespaceManager);
if (typeName == null && typeChild != null)
{
typeName = typeChild.Attributes["name"].Value;
foreach (XmlNode childNode in typeChild.ChildNodes)
parameters.Add(childNode.Attributes["name"].Value, childNode.InnerText.Trim());
}
TypeDef typeDef = mappings.GetTypeDef(typeName);
if (typeDef != null)
{
typeName = typeDef.TypeClass;
// parameters on the property mapping should
// override parameters in the typedef
Dictionary<string, string> allParameters = new Dictionary<string, string>(typeDef.Parameters);
ArrayHelper.AddAll<string, string>(allParameters, parameters);
parameters = allParameters;
}
if (!(parameters.Count == 0))
simpleValue.TypeParameters = parameters;
if (typeName != null)
simpleValue.TypeName = typeName;
}
private void BindColumnsOrFormula(XmlNode node, SimpleValue simpleValue, string path, bool isNullable)
{
XmlAttribute formulaNode = node.Attributes["formula"];
if (formulaNode != null)
{
Formula f = new Formula();
f.FormulaString = formulaNode.InnerText;
simpleValue.AddFormula(f);
}
else
BindColumns(node, simpleValue, isNullable, true, path);
}
private void AddManyToOneSecondPass(ManyToOne manyToOne)
{
mappings.AddSecondPass(delegate(IDictionary<string, PersistentClass> persistentClasses)
{ manyToOne.CreatePropertyRefConstraints(persistentClasses); });
}
protected void BindManyToOne(XmlNode node, ManyToOne model, string defaultColumnName, bool isNullable)
{
BindColumns(node, model, isNullable, true, defaultColumnName);
InitOuterJoinFetchSetting(node, model);
InitLaziness(node, model, true);
XmlAttribute ukName = node.Attributes["property-ref"];
if (ukName != null)
model.ReferencedPropertyName = ukName.Value;
model.ReferencedEntityName = GetEntityName(node, mappings);
string notFound = XmlHelper.GetAttributeValue(node, "not-found");
model.IsIgnoreNotFound = "ignore".Equals(notFound);
if (ukName != null && !model.IsIgnoreNotFound)
{
if (!"many-to-many".Equals(node.Name))
{
AddManyToOneSecondPass(model);
}
}
XmlAttribute fkNode = node.Attributes["foreign-key"];
if (fkNode != null)
model.ForeignKeyName = fkNode.Value;
}
protected void BindAny(XmlNode node, Any model, bool isNullable)
{
IType idt = GetTypeFromXML(node);
if (idt != null)
model.IdentifierTypeName = idt.Name;
XmlAttribute metaAttribute = node.Attributes["meta-type"];
if (metaAttribute != null)
{
model.MetaType = metaAttribute.Value;
XmlNodeList metaValues = node.SelectNodes(HbmConstants.nsMetaValue, namespaceManager);
if (metaValues != null && metaValues.Count > 0)
{
IDictionary<object, string> values = new Dictionary<object, string>();
IType metaType = TypeFactory.HeuristicType(model.MetaType);
foreach (XmlNode metaValue in metaValues)
try
{
object value = ((IDiscriminatorType) metaType).StringToObject(metaValue.Attributes["value"].Value);
string entityName = GetClassName(metaValue.Attributes["class"].Value, mappings);
values[value] = entityName;
}
catch (InvalidCastException)
{
throw new MappingException("meta-type was not an IDiscriminatorType: " + metaType.Name);
}
catch (HibernateException he)
{
throw new MappingException("could not interpret meta-value", he);
}
catch (TypeLoadException cnfe)
{
throw new MappingException("meta-value class not found", cnfe);
}
model.MetaValues = values.Count > 0 ? values : null;
}
}
BindColumns(node, model, isNullable, false, null);
}
private void BindOneToOne(XmlNode node, OneToOne model)
{
//BindColumns( node, model, isNullable, false, null, mappings );
XmlAttribute constrNode = node.Attributes["constrained"];
bool constrained = constrNode != null && constrNode.Value.Equals("true");
model.IsConstrained = constrained;
model.ForeignKeyType = (constrained
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?