예제 #1
0
 public void removeChildRelationship(CswNbtViewRelationship ChildRelationship)
 {
     ChildRelationships.Remove(ChildRelationship);
     ChildRelationship.Parent = null;
 }
예제 #2
0
        /// <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();
        }
예제 #3
0
 public void addChildRelationship(CswNbtViewRelationship ChildRelationship)
 {
     ChildRelationships.Add(ChildRelationship);
     ChildRelationship.Parent = this;
 }