private static Property GetPropertyOrNull(PersistentClass classMapping, string propertyName) { try { return classMapping.GetProperty(propertyName); } catch (MappingException) { return null; } }
/// <summary> /// Add the properties for an entity. /// </summary> /// <param name="meta"></param> /// <param name="pClass"></param> /// <param name="dataList">will be populated with the data properties of the entity</param> /// <param name="navList">will be populated with the navigation properties of the entity</param> void AddClassProperties(IClassMetadata meta, PersistentClass pClass, List<Dictionary<string, object>> dataList, List<Dictionary<string, object>> navList) { // Hibernate identifiers are excluded from the list of data properties, so we have to add them separately if (meta.HasIdentifierProperty) { var dmap = MakeDataProperty(meta.IdentifierPropertyName, meta.IdentifierType.Name, false, null, true, false); dataList.Add(dmap); } else if (meta.IdentifierType != null && meta.IdentifierType.IsComponentType) { // composite key is a ComponentType var compType = (ComponentType) meta.IdentifierType; var compNames = compType.PropertyNames; for (int i = 0; i < compNames.Length; i++) { var dmap = MakeDataProperty(compNames[i], compType.Subtypes[i].Name, compType.PropertyNullability[i], null, true, false); dataList.Add(dmap); } } var propNames = meta.PropertyNames; var propTypes = meta.PropertyTypes; var propNull = meta.PropertyNullability; for (int i = 0; i < propNames.Length; i++) { var propType = propTypes[i]; var propName = propNames[i]; var propColumns = pClass.GetProperty(propName).ColumnIterator.ToList(); if (propType.IsAssociationType) { // navigation property var atype = (IAssociationType)propType; var nmap = new Dictionary<string, object>(); navList.Add(nmap); nmap.Add("nameOnServer", propName); var entityType = GetEntityType(propType.ReturnedClass, propType.IsCollectionType); nmap.Add("entityTypeName", entityType.Name + ":#" + entityType.Namespace); nmap.Add("isScalar", !propType.IsCollectionType); // the associationName must be the same at both ends of the association. nmap.Add("associationName", GetAssociationName(pClass.MappedClass.Name, entityType.Name, (atype is OneToOneType))); // The foreign key columns usually applies for many-to-one associations IList<string> fks = null; if (propColumns.Any()) { fks = propColumns.Select(c => c.Text).ToList(); nmap.Add("foreignKeyNamesOnServer", fks); } } else if (propType.IsComponentType) { // complex type var compType = (ComponentType)propType; var complexTypeName = AddComponent(compType, propColumns); var compMap = new Dictionary<string, object>(); compMap.Add("nameOnServer", propName); compMap.Add("complexTypeName", complexTypeName); compMap.Add("isNullable", propNull[i]); dataList.Add(compMap); } else { // data property var col = propColumns.Count() == 1 ? propColumns[0] as Column : null; var isKey = meta.HasNaturalIdentifier && meta.NaturalIdentifierProperties.Contains(i); var isVersion = meta.IsVersioned && i == meta.VersionProperty; var dmap = MakeDataProperty(propName, propType.Name, propNull[i], col, isKey, isVersion); dataList.Add(dmap); } // TODO add validators to the property. } }
bool hasOwnProperty(PersistentClass pClass, string propName) { return pClass.GetProperty(propName).PersistentClass == pClass; }
/// <summary> /// Add the properties for an entity. /// </summary> /// <param name="meta"></param> /// <param name="pClass"></param> /// <param name="dataList">will be populated with the data properties of the entity</param> /// <param name="navList">will be populated with the navigation properties of the entity</param> void AddClassProperties(IClassMetadata meta, PersistentClass pClass, List<Dictionary<string, object>> dataList, List<Dictionary<string, object>> navList) { // maps column names to their related data properties. Used in MakeAssociationProperty to convert FK column names to entity property names. var relatedDataPropertyMap = new Dictionary<string, Dictionary<string, object>>(); var persister = meta as AbstractEntityPersister; var type = pClass.MappedClass; var propNames = meta.PropertyNames; var propTypes = meta.PropertyTypes; var propNull = meta.PropertyNullability; for (int i = 0; i < propNames.Length; i++) { var propName = propNames[i]; var pClassProp = pClass.GetProperty(propName); if (!hasOwnProperty(pClass, pClassProp)) continue; // skip property defined on superclass var propType = propTypes[i]; if (!propType.IsAssociationType) // skip association types until we handle all the data types, so the relatedDataPropertyMap will be populated. { var propColumns = pClassProp.ColumnIterator.ToList(); if (propType.IsComponentType) { // complex type var compType = (ComponentType)propType; var complexTypeName = AddComponent(compType, propColumns); var compMap = new Dictionary<string, object>(); compMap.Add("nameOnServer", propName); compMap.Add("complexTypeName", complexTypeName); compMap.Add("isNullable", propNull[i]); dataList.Add(compMap); } else { // data property var col = propColumns.Count() == 1 ? propColumns[0] as Column : null; var isKey = meta.HasNaturalIdentifier && meta.NaturalIdentifierProperties.Contains(i); var isVersion = meta.IsVersioned && i == meta.VersionProperty; var dmap = MakeDataProperty(propName, propType.Name, propNull[i], col, isKey, isVersion); dataList.Add(dmap); var columnNameString = GetPropertyColumnNames(persister, propName); relatedDataPropertyMap.Add(columnNameString, dmap); } } } // Hibernate identifiers are excluded from the list of data properties, so we have to add them separately if (meta.HasIdentifierProperty && hasOwnProperty(pClass, meta.IdentifierPropertyName)) { var dmap = MakeDataProperty(meta.IdentifierPropertyName, meta.IdentifierType.Name, false, null, true, false); dataList.Insert(0, dmap); var columnNameString = GetPropertyColumnNames(persister, meta.IdentifierPropertyName); relatedDataPropertyMap.Add(columnNameString, dmap); } else if (meta.IdentifierType != null && meta.IdentifierType.IsComponentType && pClass.Identifier is Component && ((Component)pClass.Identifier).Owner == pClass) { // composite key is a ComponentType var compType = (ComponentType)meta.IdentifierType; var compNames = compType.PropertyNames; for (int i = 0; i < compNames.Length; i++) { var compName = compNames[i]; var propType = compType.Subtypes[i]; if (!propType.IsAssociationType) { var dmap = MakeDataProperty(compName, propType.Name, compType.PropertyNullability[i], null, true, false); dataList.Insert(0, dmap); } else { var manyToOne = propType as ManyToOneType; //var joinable = manyToOne.GetAssociatedJoinable(this._sessionFactory); var propColumnNames = GetPropertyColumnNames(persister, compName); var assProp = MakeAssociationProperty(type, (IAssociationType)propType, compName, propColumnNames, pClass, relatedDataPropertyMap, true); navList.Add(assProp); } } } // We do the association properties after the data properties, so we can do the foreign key lookups for (int i = 0; i < propNames.Length; i++) { var propName = propNames[i]; if (!hasOwnProperty(pClass, propName)) continue; // skip property defined on superclass var propType = propTypes[i]; if (propType.IsAssociationType) { // navigation property var propColumnNames = GetPropertyColumnNames(persister, propName); var assProp = MakeAssociationProperty(type, (IAssociationType)propType, propName, propColumnNames, pClass, relatedDataPropertyMap, false); navList.Add(assProp); } } }
private static Property FindPropertyByName(PersistentClass associatedClass, string propertyName) { Property property; Property idProperty = associatedClass.IdentifierProperty; string idName = idProperty != null ? idProperty.Name : null; try { //if it's a Id if (string.IsNullOrEmpty(propertyName) || propertyName.Equals(idName)) property = idProperty; else //if it's a property { property = associatedClass.GetProperty(propertyName); } } catch (MappingException) { #region Unsupported future of NH2.0 //try //{ //if we do not find it try to check the identifier mapper //if (associatedClass.IdentifierMapper == null) return null; //StringTokenizer st = new StringTokenizer(propertyName, ".", false); //foreach (string element in st) //{ // if (property == null) // { // property = associatedClass.IdentifierMapper.GetProperty(element); // } // else // { // if (property.IsComposite) // property = ((Component)property.Value).GetProperty(element); // else // return null; // } //} //} //catch (MappingException) //{ return null; //} #endregion } return property; }
/// <summary> /// Make association property metadata for the entity. /// Also populates the _fkMap which is used for related-entity fixup in NHContext.FixupRelationships /// </summary> /// <param name="propType"></param> /// <param name="propName"></param> /// <param name="pClass"></param> /// <param name="relatedDataPropertyMap"></param> /// <returns></returns> private Dictionary<string, object> MakeAssociationProperty(IAssociationType propType, string propName, PersistentClass pClass, Dictionary<string, string> relatedDataPropertyMap) { var nmap = new Dictionary<string, object>(); nmap.Add("nameOnServer", propName); var entityType = GetEntityType(propType.ReturnedClass, propType.IsCollectionType); nmap.Add("entityTypeName", entityType.Name + ":#" + entityType.Namespace); nmap.Add("isScalar", !propType.IsCollectionType); // the associationName must be the same at both ends of the association. nmap.Add("associationName", GetAssociationName(pClass.MappedClass.Name, entityType.Name, (propType is OneToOneType))); // The foreign key columns usually applies for many-to-one and one-to-one associations if (!propType.IsCollectionType) { IList<string> fks = null; var propColumns = pClass.GetProperty(propName).ColumnIterator; if (propColumns.Any()) // foreign key columns are defined { fks = propColumns.Select(c => c.Text).ToList(); } else // foreign key is same as primary key of related entity { var relatedPersistentClass = _configuration.GetClassMapping(entityType); var key = relatedPersistentClass.Key as SimpleValue; if (key != null) { fks = key.ColumnIterator.Select(c => c.Text).ToList(); } } if (fks != null) { var entityRelationship = pClass.EntityName + '.' + propName; var columnNameString = string.Join(",", fks); string relatedDataProperty; if (relatedDataPropertyMap.TryGetValue(columnNameString, out relatedDataProperty)) { nmap.Add("foreignKeyNamesOnServer", new string[] { relatedDataProperty }); _fkMap.Add(entityRelationship, relatedDataProperty); } else { nmap.Add("foreignKeyNamesOnServer", fks); _fkMap.Add(entityRelationship, fks[0]); } } } return nmap; }
/// <summary> /// Add the properties for an entity. /// </summary> /// <param name="meta"></param> /// <param name="pClass"></param> /// <param name="dataList">will be populated with the data properties of the entity</param> /// <param name="navList">will be populated with the navigation properties of the entity</param> void AddClassProperties(IClassMetadata meta, PersistentClass pClass, List<Dictionary<string, object>> dataList, List<Dictionary<string, object>> navList) { // Hibernate identifiers are excluded from the list of data properties, so we have to add them separately if (meta.HasIdentifierProperty) { var dmap = MakeDataProperty(meta.IdentifierPropertyName, meta.IdentifierType.Name, false, null, true, false); dataList.Add(dmap); } else if (meta.IdentifierType != null && meta.IdentifierType.IsComponentType) { // composite key is a ComponentType var compType = (ComponentType) meta.IdentifierType; var compNames = compType.PropertyNames; for (int i = 0; i < compNames.Length; i++) { var dmap = MakeDataProperty(compNames[i], compType.Subtypes[i].Name, compType.PropertyNullability[i], null, true, false); dataList.Add(dmap); } } // maps column names to their related data properties. Used in MakeAssociationProperty to convert FK column names to entity property names. var relatedDataPropertyMap = new Dictionary<string, string>(); var propNames = meta.PropertyNames; var propTypes = meta.PropertyTypes; var propNull = meta.PropertyNullability; for (int i = 0; i < propNames.Length; i++) { var propType = propTypes[i]; if (!propType.IsAssociationType) // skip association types until below { var propName = propNames[i]; var propColumns = pClass.GetProperty(propName).ColumnIterator.ToList(); if (propType.IsComponentType) { // complex type var compType = (ComponentType)propType; var complexTypeName = AddComponent(compType, propColumns); var compMap = new Dictionary<string, object>(); compMap.Add("nameOnServer", propName); compMap.Add("complexTypeName", complexTypeName); compMap.Add("isNullable", propNull[i]); dataList.Add(compMap); } else { // data property var col = propColumns.Count() == 1 ? propColumns[0] as Column : null; var isKey = meta.HasNaturalIdentifier && meta.NaturalIdentifierProperties.Contains(i); var isVersion = meta.IsVersioned && i == meta.VersionProperty; var dmap = MakeDataProperty(propName, propType.Name, propNull[i], col, isKey, isVersion); dataList.Add(dmap); var columnNameString = string.Join(",", propColumns.Select(c => c.Text)); relatedDataPropertyMap.Add(columnNameString, propName); } // TODO add validators to the property. } } // We do the association properties after the data properties, so we can do the foreign key lookups for (int i = 0; i < propNames.Length; i++) { var propType = propTypes[i]; if (propType.IsAssociationType) { // navigation property var propName = propNames[i]; var assProp = MakeAssociationProperty((IAssociationType)propType, propName, pClass, relatedDataPropertyMap); navList.Add(assProp); } } }