public void removeChildRelationship(CswNbtViewRelationship ChildRelationship) { ChildRelationships.Remove(ChildRelationship); ChildRelationship.Parent = null; }
/// <summary> /// Creates a new instance of <see cref="TableMapping"/> /// </summary> /// <param name="entityType"></param> public TableMapping(Type entityType) { // Set critical properties this.EntityType = entityType; this.TableName = entityType.Name; this.ParentRelationships = new Dictionary <PropertyInfo, Type>(); this.ChildRelationships = new Dictionary <PropertyInfo, Type>(); // Get table related instructions var tableAttr = (TableAttribute)entityType.GetCustomAttribute(typeof(TableAttribute)); if (tableAttr != null) { this.TableName = tableAttr.Name ?? entityType.Name; this.WithoutRowID = tableAttr.WithoutRowID; this.BuildInstanceForeignKeys = tableAttr.BuildInstanceRelationships; } // Temporary variables Dictionary <string, AttributeInfo> cols = new Dictionary <string, AttributeInfo>(); List <AttributeInfo> primaryKeys = new List <AttributeInfo>(); // Get a list of properties from the Entity that represents an Attribute var props = entityType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); // Loop through each attribute, and generate an attribute map foreach (PropertyInfo property in props) { // Grab type Type type = property.PropertyType; // Column attribute? if (Attribute.IsDefined(property, typeof(ColumnAttribute))) { // Create our attribute info class AttributeInfo info = new AttributeInfo(); info.Property = property; // Now itterate through each attribute foreach (Attribute attr in property.GetCustomAttributes()) { Type attrType = attr.GetType(); if (attrType == typeof(ColumnAttribute)) { // Get our attribute name ColumnAttribute colAttr = (ColumnAttribute)attr; info.Name = colAttr.Name ?? property.Name; } else if (attrType == typeof(ForeignKeyAttribute)) { throw new EntityException($"Invalid foreign key attribute on {entityType.Name}.{property.Name}"); } else if (attrType == typeof(PrimaryKeyAttribute)) { // Check for RowID Alias column (INTEGER PRIMARY KEY) if (info.Property.PropertyType.IsInteger()) { if (primaryKeys.Count == 0) { RowIdColumn = info; } else { RowIdColumn = null; } } // Add primary key to the list info.PrimaryKey = true; primaryKeys.Add(info); } else if (attrType == typeof(DefaultAttribute)) { info.DefaultValue = (DefaultAttribute)attr; } else if (attrType == typeof(RequiredAttribute)) { info.HasRequiredAttribute = true; } else if (attrType == typeof(UniqueAttribute)) { info.Unique = true; } else if (attrType == typeof(CollationAttribute)) { info.Collation = ((CollationAttribute)attr).Collation; } else if (attrType == typeof(AutoIncrementAttribute)) { // Cannot have more than 1 auto increment column if (AutoIncrementAttribute != null) { throw new EntityException($"Entity `{EntityType.Name}` cannot contain multiple AutoIncrement attributes."); } // set values AutoIncrementAttribute = info; info.AutoIncrement = true; } } // Add to column list cols[info.Name] = info; } // Check for foreign key collections else if (property.GetGetMethod(true).IsVirtual) { // All generics are Lazy-Loaded if (type.IsGenericType) { Type def = type.GetGenericTypeDefinition(); type = type.GenericTypeArguments[0]; if (def == typeof(IEnumerable <>)) { // IEnumerable means this is a parent entity ChildRelationships.Add(property, type); } else if (def == typeof(ForeignKey <>)) { // If no foreign key attribute is defined, tell the dev if (!Attribute.IsDefined(property, typeof(ForeignKeyAttribute))) { throw new EntityException("Properties of type ForeignKey<T> must contain the ForeignKey attribute"); } // ForeignKey<T> means this is a child entity ParentRelationships.Add(property, type); } } else if (Attribute.IsDefined(property, typeof(ForeignKeyAttribute))) { // Eager Loaded Property! ParentRelationships.Add(property, type); } } } // Check for unique composites UniqueConstraints = entityType.GetCustomAttributes <CompositeUniqueAttribute>().ToList().AsReadOnly(); // Set internals Columns = new ReadOnlyDictionary <string, AttributeInfo>(cols); PrimaryKeys = primaryKeys.Select(x => x.Name).ToList().AsReadOnly(); List <ForeignKeyConstraint> foreignKeys = new List <ForeignKeyConstraint>(); // ------------------------------------ // Always check foreign keys after setting the Columns property! // // We must always check foreign keys after loading all of the entities properties, // because the properties may not be ordered correctly in the class itself. This // would cause errors when checking for column matches between the parent // and child entities when creating the ForeignKeyInfo class. // ------------------------------------ // Loop through each attribute, and generate an attribute map foreach (PropertyInfo property in ParentRelationships.Keys) { var fkey = (ForeignKeyAttribute)property.GetCustomAttribute(typeof(ForeignKeyAttribute)); var inverse = (InverseKeyAttribute)property.GetCustomAttribute(typeof(InverseKeyAttribute)); // Grab generic type Type parentType = (property.PropertyType.IsGenericType) ? property.PropertyType.GetGenericArguments()[0] : property.PropertyType; // Create ForeignKeyInfo InverseKeyAttribute inv = inverse ?? new InverseKeyAttribute(fkey.Attributes); ForeignKeyConstraint info = new ForeignKeyConstraint(this, property.Name, parentType, fkey, inv); foreignKeys.Add(info); } // Finally, set our class ForeignKey property ForeignKeys = foreignKeys.AsReadOnly(); }
public void addChildRelationship(CswNbtViewRelationship ChildRelationship) { ChildRelationships.Add(ChildRelationship); ChildRelationship.Parent = this; }