internal MetaTable GetTableNoLocks(Type rowType) { MetaTable table; if (!this.metaTables.TryGetValue(rowType, out table)) { Type root = GetRoot(rowType) ?? rowType; TableAttribute[] attrs = (TableAttribute[])root.GetCustomAttributes(typeof(TableAttribute), true); if (attrs.Length == 0) { this.metaTables.Add(rowType, null); } else { if (!this.metaTables.TryGetValue(root, out table)) { table = new AttributedMetaTable(this, attrs[0], root); foreach (MetaType mt in table.RowType.InheritanceTypes) { this.metaTables.Add(mt.Type, table); } } // catch case of derived type that is not part of inheritance if (table.RowType.GetInheritanceType(rowType) == null) { this.metaTables.Add(rowType, null); return(null); } } } return(table); }
internal AttributedRootType(AttributedMetaModel model, AttributedMetaTable table, Type type) : base(model, table, type, null) { // check for inheritance and create all other types InheritanceMappingAttribute[] inheritanceInfo = (InheritanceMappingAttribute[])type.GetCustomAttributes(typeof(InheritanceMappingAttribute), true); if (inheritanceInfo.Length > 0) { if (this.Discriminator == null) { throw Error.NoDiscriminatorFound(type); } if (!MappingSystem.IsSupportedDiscriminatorType(this.Discriminator.Type)) { throw Error.DiscriminatorClrTypeNotSupported(this.Discriminator.DeclaringType.Name, this.Discriminator.Name, this.Discriminator.Type); } this.types = new Dictionary <Type, MetaType>(); this.types.Add(type, this); // add self this.codeMap = new Dictionary <object, MetaType>(); // initialize inheritance types foreach (InheritanceMappingAttribute attr in inheritanceInfo) { if (!type.IsAssignableFrom(attr.Type)) { throw Error.InheritanceTypeDoesNotDeriveFromRoot(attr.Type, type); } if (attr.Type.IsAbstract) { throw Error.AbstractClassAssignInheritanceDiscriminator(attr.Type); } AttributedMetaType mt = this.CreateInheritedType(type, attr.Type); if (attr.Code == null) { throw Error.InheritanceCodeMayNotBeNull(); } if (mt.inheritanceCode != null) { throw Error.InheritanceTypeHasMultipleDiscriminators(attr.Type); } //object codeValue = DBConvert.ChangeType(*/attr.Code/*, this.Discriminator.Type); object codeValue = attr.Code; foreach (object d in codeMap.Keys) { // if the keys are equal, or if they are both strings containing only spaces // they are considered equal if ((codeValue.GetType() == typeof(string) && ((string)codeValue).Trim().Length == 0 && d.GetType() == typeof(string) && ((string)d).Trim().Length == 0) || object.Equals(d, codeValue)) { throw Error.InheritanceCodeUsedForMultipleTypes(codeValue); } } mt.inheritanceCode = codeValue; this.codeMap.Add(codeValue, mt); if (attr.IsDefault) { if (this.InheritanceDefault != null) { throw Error.InheritanceTypeHasMultipleDefaults(type); } this.InheritanceDefault = mt; } } if (this.InheritanceDefault == null) { throw Error.InheritanceHierarchyDoesNotDefineDefault(type); } } if (this.types != null) { this.InheritanceTypes = this.types.Values.ToList().AsReadOnly(); } else { this.InheritanceTypes = new MetaType[] { this }.ToList().AsReadOnly(); } Validate(); }