示例#1
0
        private void ProcessManyToManyReference(
			Entity entity,
			DirectedReference directedReference,
			Action<object> addItem,
			Dictionary<ITable, int> manyToManySameTableProcessingCounts,
			string collectionCascade,
			string lazy,
			string orderByClause,
			bool inverse)
        {
            if (directedReference.FromEndEnabled == false) return;

            ITable referenceMappedTable = directedReference.Reference.MappedTable();

            ITable fromPrimaryMappedTable = EntityMapper.GetPrimaryTable(entity);
            ITable toPrimaryMappedTable = EntityMapper.GetPrimaryTable(directedReference.ToEntity);
            Cardinality cardinalityPrimary;
            Cardinality cardinalityForeign;
            IKey mainKey;
            IKey associationKey;
            ITable associationTable = entity.GetAssociationTable(directedReference.ToEntity, out cardinalityPrimary, out cardinalityForeign, out mainKey, out associationKey);

            key keyNode = new key();
            List<IColumn> fromInPrimaryKey = new List<IColumn>();
            List<IColumn> toInPrimaryKey = new List<IColumn>();

            if (fromPrimaryMappedTable == toPrimaryMappedTable)
            {
                // This many-to-many relationship is to the same table
                if (manyToManySameTableProcessingCounts.ContainsKey(toPrimaryMappedTable))
                {
                    int index = manyToManySameTableProcessingCounts[toPrimaryMappedTable];
                    index++;
                    fromInPrimaryKey.AddRange(referenceMappedTable.Relationships.Where(t => t.PrimaryTable == fromPrimaryMappedTable).ElementAt(index).PrimaryKey.Columns);
                    toInPrimaryKey.AddRange(referenceMappedTable.Relationships.Where(t => t.PrimaryTable == toPrimaryMappedTable).ElementAt(index).ForeignKey.Columns);
                    manyToManySameTableProcessingCounts[toPrimaryMappedTable] = index;
                }
                else
                {
                    fromInPrimaryKey.AddRange(referenceMappedTable.Relationships.Where(t => t.PrimaryTable == fromPrimaryMappedTable).ElementAt(0).PrimaryKey.Columns);
                    toInPrimaryKey.AddRange(referenceMappedTable.Relationships.Where(t => t.PrimaryTable == toPrimaryMappedTable).ElementAt(0).ForeignKey.Columns);
                    manyToManySameTableProcessingCounts.Add(toPrimaryMappedTable, 0);
                }
            }
            else
            {
                foreach (var coll in referenceMappedTable.Relationships.Where(t => t.PrimaryTable == fromPrimaryMappedTable).Select(r => r.ForeignKey.Columns))
                    foreach (var c in coll)
                        fromInPrimaryKey.Add(c);

                foreach (var coll in referenceMappedTable.Relationships.Where(t => t.PrimaryTable == toPrimaryMappedTable).Select(r => r.ForeignKey.Columns))
                    foreach (var c in coll)
                        toInPrimaryKey.Add(c);
            }

            if (fromInPrimaryKey.Count() == 1)
                keyNode.column1 = fromInPrimaryKey.First().Name.BackTick();
            else
                foreach (var columnNode in GetColumnNodes(fromInPrimaryKey))
                    keyNode.AddColumn(columnNode);

            manytomany manyToManyNode = new manytomany();
            manyToManyNode.@class = directedReference.ToEntity.Name;

            if (toInPrimaryKey.Count() == 1)
                manyToManyNode.column = toInPrimaryKey.First().Name.BackTick();
            else
                foreach (var columnNode in GetColumnNodes(toInPrimaryKey))
                    keyNode.AddColumn(columnNode);

            collectionFetchMode collFetchMode;

            if (directedReference.Entity1IsFromEnd)
                collFetchMode = (collectionFetchMode)Enum.Parse(typeof(collectionFetchMode), directedReference.Reference.GetReferenceEnd1CollectionFetchMode().ToString(), true);
            else
                collFetchMode = (collectionFetchMode)Enum.Parse(typeof(collectionFetchMode), directedReference.Reference.GetReferenceEnd2CollectionFetchMode().ToString(), true);

            AssociationType type = NHCollections.GetAssociationType(directedReference);

            switch (type)
            {
                case AssociationType.None:
                    Log.WarnFormat("No association type was set on reference {0} for the end {1}. This is usually an error.", directedReference.Reference.Name, directedReference.Entity1IsFromEnd ? "One" : "Two");
                    return;
                case AssociationType.Set:
                    set setNode = CreateSetNode(directedReference, keyNode, collectionCascade, collFetchMode, lazy, inverse);
                    setNode.table = referenceMappedTable.Name.BackTick();
                    setNode.Item = manyToManyNode;

                    if (orderByClause.Length > 0)
                        setNode.orderby = orderByClause;

                    addItem(setNode);
                    break;
                case AssociationType.Bag:
                    bag bagNode = CreateBagNode(directedReference, keyNode, collectionCascade, collFetchMode, lazy, inverse);
                    bagNode.table = referenceMappedTable.Name.BackTick();
                    bagNode.Item = manyToManyNode;

                    if (orderByClause.Length > 0)
                        bagNode.orderby = orderByClause;

                    addItem(bagNode);
                    break;
                case AssociationType.Map:
                    map mapNode = CreateMapNode(directedReference, keyNode, collectionCascade, collFetchMode, lazy, inverse);
                    mapNode.table = referenceMappedTable.Name.BackTick();
                    mapNode.Item = new index
                                        {
                                            column1 = NHCollections.GetIndexColumnName(directedReference),
                                            type = NHCollections.GetIndexColumnTypeName(directedReference, toPrimaryMappedTable /*fromPrimaryMappedTable*/)
                                        };
                    mapNode.Item1 = manyToManyNode;

                    if (orderByClause.Length > 0)
                        mapNode.orderby = orderByClause;

                    addItem(mapNode);
                    break;
                case AssociationType.List:
                    list listNode = CreateListNode(directedReference, keyNode, collectionCascade, collFetchMode, lazy, inverse);
                    listNode.table = referenceMappedTable.Name.BackTick();
                    listNode.Item = new index
                    {
                        column1 = NHCollections.GetIndexColumnName(directedReference),
                    };
                    listNode.Item1 = manyToManyNode;

                    if (orderByClause.Length > 0)
                        listNode.orderby = orderByClause;

                    addItem(listNode);
                    break;
                // case AssociationType.IDBag:
                //     throw new NotImplementedException(
                //         string.Format("Have not implemented {0} association type for Many To Many relationships", type));
                default:
                    throw new NotImplementedException("AssociationType not handled yet: " + type.ToString());
            }
        }
示例#2
0
        private void ProcessCollection(
			@class hClass,
			key keyNode,
			index indexNode,
			manytomany many,
			string className,
			string schema,
			string tableName,
			string propertyName,
			string cascade,
			AssociationType associationType,
			string whereClause,
			collectionFetchMode fetchMode,
			bool inverse,
			collectionLazy lazy,
			string orderByClause)
        {
            #region OrderBy
            string orderByPropertyName = "";
            bool orderByIsAsc = true;

            if (!string.IsNullOrWhiteSpace(orderByClause))
            {
                orderByClause = orderByClause.Trim();

                if (orderByClause.EndsWith(" desc", StringComparison.InvariantCultureIgnoreCase))
                {
                    orderByIsAsc = false;
                    orderByPropertyName = orderByClause.Substring(0, orderByClause.LastIndexOf(" desc", StringComparison.InvariantCultureIgnoreCase)).Trim();
                }
                else if (orderByClause.EndsWith(" asc", StringComparison.InvariantCultureIgnoreCase))
                {
                    orderByIsAsc = false;
                    orderByPropertyName = orderByClause.Substring(0, orderByClause.LastIndexOf(" asc", StringComparison.InvariantCultureIgnoreCase)).Trim();
                }
                else
                    orderByPropertyName = orderByClause;
            }
            #endregion

            string indexName = null;

            if (indexNode != null)
            {
                if (indexNode.column != null && indexNode.column.Count() > 0)
                    indexName = indexNode.column[0].name;
                else
                    indexName = indexNode.column1;
            }
            if (many != null)
            {
                var fkColumns = GetColumnNames(many.column, many.Columns()).ToList();
                string thisEntityName;
                string otherEntityName;
                EntityLoader.IsNameFullyQualified(hClass.name, out thisEntityName);
                EntityLoader.IsNameFullyQualified(many.@class, out otherEntityName);

                var collectionInfo = new AssociationInformation
                                        {
                                            PropertyName = propertyName,
                                            ForeignKeyColumnNames = fkColumns,
                                            ForeignKeyBelongsToThisTable = !ForeignKeyBelongsToThisTable(hClass, fkColumns),
                                            AssociationTableName = new AssociationInformation.TableNameType(schema, tableName),
                                            ThisEntityName = thisEntityName,
                                            OtherEntityName = otherEntityName,
                                            Cardinality = Cardinality.Many,
                                            CollectionCascade = ArchAngel.Interfaces.NHibernateEnums.Helper.GetCollectionCascadeType(cascade),
                                            CollectionLazy = ArchAngel.Interfaces.NHibernateEnums.Helper.GetCollectionLazyType(lazy.ToString()),
                                            CollectionFetchMode = (CollectionFetchModes)Enum.Parse(typeof(CollectionFetchModes), fetchMode.ToString(), true),
                                            IndexColumn = indexName,
                                            WhereClause = whereClause,
                                            AssociationType = associationType,
                                            Inverse = inverse ? ArchAngel.Interfaces.NHibernateEnums.BooleanInheritedTypes.@true : ArchAngel.Interfaces.NHibernateEnums.BooleanInheritedTypes.@false,
                                            OrderByColumnName = orderByPropertyName,
                                            OrderByIsAsc = orderByIsAsc
                                        };
                associationInformation.Add(collectionInfo);
            }
            else
            {
                var fkColumns = GetColumnNames(keyNode.column1, keyNode.Columns()).ToList();
                string thisEntityName;
                string otherEntityName;
                EntityLoader.IsNameFullyQualified(hClass.name, out thisEntityName);
                EntityLoader.IsNameFullyQualified(className, out otherEntityName);

                bool topLevelInverse = ArchAngel.Interfaces.SharedData.CurrentProject.GetProjectDefaultInverse();
                BooleanInheritedTypes inverseValue = inverse ? BooleanInheritedTypes.@true : BooleanInheritedTypes.@false;

                if ((inverseValue == BooleanInheritedTypes.@false && topLevelInverse == false) ||
                    (inverseValue == BooleanInheritedTypes.@true && topLevelInverse == true))
                    inverseValue = BooleanInheritedTypes.inherit_default;

                var collectionInfo = new AssociationInformation
                                        {
                                            PropertyName = propertyName,
                                            ForeignKeyColumnNames = fkColumns,
                                            ForeignKeyBelongsToThisTable = ForeignKeyBelongsToThisTable(hClass, fkColumns), // GFH
                                            ThisEntityName = thisEntityName,
                                            OtherEntityName = otherEntityName,
                                            Cardinality = Cardinality.Many,
                                            CollectionCascade = ArchAngel.Interfaces.NHibernateEnums.Helper.GetCollectionCascadeType(cascade),
                                            CollectionLazy = ArchAngel.Interfaces.NHibernateEnums.Helper.GetCollectionLazyType(lazy.ToString()),
                                            CollectionFetchMode = (CollectionFetchModes)Enum.Parse(typeof(CollectionFetchModes), fetchMode.ToString(), true),
                                            IndexColumn = indexName,
                                            AssociationType = associationType,
                                            Inverse = inverseValue,
                                            OrderByColumnName = orderByPropertyName,
                                            OrderByIsAsc = orderByIsAsc
                                        };
                associationInformation.Add(collectionInfo);
            }
        }