private bool IsType(TypeMapping map, Type type) { if (string.Compare(map.Name, type.Name, StringComparison.Ordinal) == 0 || string.Compare(map.Name, type.FullName, StringComparison.Ordinal) == 0 || string.Compare(map.Name, type.AssemblyQualifiedName, StringComparison.Ordinal) == 0) return true; foreach (TypeMapping subMap in map.DerivedTypes) { if (this.IsType(subMap, type)) return true; } return false; }
private object locktarget = new object(); // Hold locks on private object rather than public MetaType. #endregion internal MappedType(MetaModel model, MetaTable table, TypeMapping typeMapping, Type type, MetaType inheritanceRoot) { this.model = model; this.table = table; this.typeMapping = typeMapping; this.type = type; this.inheritanceRoot = inheritanceRoot != null ? inheritanceRoot : this; this.InitDataMembers(); this.identities = this.dataMembers.Where(m => m.IsPrimaryKey).ToList().AsReadOnly(); this.persistentDataMembers = this.dataMembers.Where(m => m.IsPersistent).ToList().AsReadOnly(); }
[ResourceConsumption(ResourceScope.Assembly | ResourceScope.Machine)] // InitInheritedType method call. public MappedRootType(MappedMetaModel model, MappedTable table, TypeMapping typeMapping, Type type) : base(model, table, typeMapping, type, null) { if(typeMapping == null) throw Error.ArgumentNull("typeMapping"); if(typeMapping.InheritanceCode != null || typeMapping.DerivedTypes.Count > 0) { if(this.Discriminator == null) { throw Error.NoDiscriminatorFound(type.Name); } this.hasInheritance = true; if(!MappingSystem.IsSupportedDiscriminatorType(this.Discriminator.Type)) { throw Error.DiscriminatorClrTypeNotSupported(this.Discriminator.DeclaringType.Name, this.Discriminator.Name, this.Discriminator.Type); } this.derivedTypes = new Dictionary<Type, MetaType>(); this.inheritanceCodes = new Dictionary<object, MetaType>(); this.InitInheritedType(typeMapping, this); } if(this.inheritanceDefault == null && (this.InheritanceCode != null || this.inheritanceCodes != null && this.inheritanceCodes.Count > 0)) throw Error.InheritanceHierarchyDoesNotDefineDefault(type); if(this.derivedTypes != null) { this.inheritanceTypes = this.derivedTypes.Values.ToList().AsReadOnly(); } else { this.inheritanceTypes = new MetaType[] { this }.ToList().AsReadOnly(); } this.Validate(); }
[ResourceConsumption(ResourceScope.Assembly | ResourceScope.Machine)] // MappedRootType constructor call. private MetaType GetMetaType(TypeMapping tm, Type elementType) { MetaTable tbl = model.GetTable(elementType); if(tbl != null) { return tbl.RowType.GetInheritanceType(elementType); } return new MappedRootType((MappedMetaModel)model, null, tm, elementType); }
[ResourceConsumption(ResourceScope.Assembly | ResourceScope.Machine)] // InitDerivedTypes method call. private MetaType InitInheritedType(TypeMapping typeMap, MappedType type) { this.derivedTypes.Add(type.Type, type); if (typeMap.InheritanceCode != null) { // Mapping with no inheritance code: For example, an unmapped intermediate class in a hierarchy. if (this.Discriminator == null) throw Error.NoDiscriminatorFound(type.Name); if (type.Type.IsAbstract) throw Error.AbstractClassAssignInheritanceDiscriminator(type.Type); object keyValue = DBConvert.ChangeType(typeMap.InheritanceCode, this.Discriminator.Type); foreach (object d in inheritanceCodes.Keys) { // if the keys are equal, or if they are both strings containing only spaces // they are considered equal if ((keyValue.GetType() == typeof(string) && ((string)keyValue).Trim().Length == 0 && d.GetType() == typeof(string) && ((string)d).Trim().Length == 0) || object.Equals(d, keyValue)) { throw Error.InheritanceCodeUsedForMultipleTypes(keyValue); } } if (type.inheritanceCode != null) throw Error.InheritanceTypeHasMultipleDiscriminators(type); type.inheritanceCode = keyValue; this.inheritanceCodes.Add(keyValue, type); if (typeMap.IsInheritanceDefault) { if (this.inheritanceDefault != null) throw Error.InheritanceTypeHasMultipleDefaults(type); this.inheritanceDefault = type; } } // init sub-inherited types foreach (TypeMapping tm in typeMap.DerivedTypes) { this.InitDerivedTypes(tm); } return type; }
[ResourceConsumption(ResourceScope.Assembly | ResourceScope.Machine)] // FindType method call. private MetaType InitDerivedTypes(TypeMapping typeMap) { Type type = ((MappedMetaModel)Model).FindType(typeMap.Name); if (type == null) throw Error.CouldNotFindRuntimeTypeForMapping(typeMap.Name); MappedType rowType = new MappedType(this.Model, this.Table, typeMap, type, this); return this.InitInheritedType(typeMap, rowType); }
private Type GetRootType(Type type, TypeMapping rootMapping) { if (string.Compare(rootMapping.Name, type.Name, StringComparison.Ordinal) == 0 || string.Compare(rootMapping.Name, type.FullName, StringComparison.Ordinal) == 0 || string.Compare(rootMapping.Name, type.AssemblyQualifiedName, StringComparison.Ordinal) == 0) return type; if (type.BaseType != typeof(object)) { return this.GetRootType(type.BaseType, rootMapping); } throw Error.UnableToResolveRootForType(type); }