예제 #1
0
        public static AssociationType GetAssociationType(DirectedReference directedReference)
        {
            string propertyName =
                directedReference.Entity1IsFromEnd ? "End1CollectionType" : "End2CollectionType";

            return((AssociationType)directedReference.Reference.GetUserOptionValue(propertyName));
        }
예제 #2
0
        public static string ProcessReferenceTemplate(Entity entity, DirectedReference reference)
        {
            System.Text.StringBuilder sb = new StringBuilder(((SourceCodeMultiLineType)SharedData.CurrentProject.GetUserOption("ReferenceTemplate")).Value);

            string typeName;

            if (reference.FromEndCardinality == ArchAngel.Interfaces.Cardinality.Many)
            {
                typeName = NHCollections.GetCollectionType(reference).Replace(SharedData.CurrentProject.GetUserOption("ProjectNamespace").ToString() + ".Model.", "");
            }
            else
            {
                typeName = reference.ToEntity.Name;
            }

            sb.Replace("#entity.Name#", entity.Name);
            sb.Replace("#reference.Name#", reference.FromName);
            sb.Replace("#reference.Type#", typeName);

            bool usePrivateSetter = (bool)SharedData.CurrentProject.GetUserOption("UsePrivateSettersOnProperties") ||
                                    (reference.Entity1IsFromEnd ? (bool)reference.Reference.GetUserOptionValue("End1UsePrivateSetter") : (bool)reference.Reference.GetUserOptionValue("End2UsePrivateSetter"));

            ProcessIfStatement(sb, "reference.SetterIsPrivate", usePrivateSetter);

            return(RemoveTrailingLineBreaks(sb.ToString()));
        }
예제 #3
0
        public static string GetIndexColumnName(DirectedReference directedReference)
        {
            string propertyName    = directedReference.Entity1IsFromEnd ? "End1IndexColumn" : "End2IndexColumn";
            string indexColumnName = (string)directedReference.Reference.GetUserOptionValue(propertyName);

            return(indexColumnName);
        }
예제 #4
0
        public static CollectionFetchModes GetFetchType(DirectedReference directedReference)
        {
            string propertyName =
                directedReference.Entity1IsFromEnd ? "Reference_End1CollectionFetchMode" : "Reference_End2CollectionFetchMode";

            return((CollectionFetchModes)directedReference.Reference.GetUserOptionValue(propertyName));
        }
예제 #5
0
        private map CreateMapNode(DirectedReference reference, key keyNode, string cascade, collectionFetchMode colFetchMode, string lazyString, bool inverse)
        {
            var lazy = (collectionLazy)Enum.Parse(typeof(collectionLazy), lazyString.ToString().Replace("_", ""), true);

            map mapNode = new map();

            mapNode.name    = reference.FromName;
            mapNode.key     = keyNode;
            mapNode.cascade = cascade == "none" ? null : cascade;
            mapNode.inverse = inverse;

            mapNode.fetchSpecified = colFetchMode != collectionFetchMode.select;
            mapNode.fetch          = colFetchMode;
            mapNode.lazySpecified  = lazy != collectionLazy.@true;
            mapNode.lazy           = (collectionLazy)Enum.Parse(typeof(collectionLazy), lazy.ToString().Replace("_", ""), true);

            var sqlWhereClause = NHCollections.GetSqlWhereClause(reference);

            if (string.IsNullOrEmpty(sqlWhereClause) == false)
            {
                mapNode.where = sqlWhereClause;
            }

            return(mapNode);
        }
예제 #6
0
        /// <summary>
        /// Gets the EndXSqlWhereClause property, or returns null if it has not been set.
        /// </summary>
        /// <param name="directedReference"></param>
        /// <returns></returns>
        public static string GetSqlWhereClause(DirectedReference directedReference)
        {
            string propertyName = directedReference.Entity1IsFromEnd ? "End1SqlWhereClause" : "End2SqlWhereClause";

            if (directedReference.Reference.HasUserOption(propertyName))
            {
                return((string)directedReference.Reference.GetUserOptionValue(propertyName));
            }

            return(null);
        }
예제 #7
0
        private manytoone CreateManyToOneNode(DirectedReference directedReference, ITable referenceMappedTable)
        {
            fetchMode fetchMode;
            bool      insert;
            bool      update;

            if (directedReference.Entity1IsFromEnd)
            {
                fetchMode = (fetchMode)Enum.Parse(typeof(fetchMode), directedReference.Reference.GetReferenceEnd1FetchMode().ToString(), true);
                insert    = directedReference.Reference.GetReferenceEnd1Insert();
                update    = directedReference.Reference.GetReferenceEnd1Update();
            }
            else
            {
                fetchMode = (fetchMode)Enum.Parse(typeof(fetchMode), directedReference.Reference.GetReferenceEnd2FetchMode().ToString(), true);
                insert    = directedReference.Reference.GetReferenceEnd2Insert();
                update    = directedReference.Reference.GetReferenceEnd2Update();
            }
            manytoone manyToOneNode = new manytoone();

            manyToOneNode.@class = directedReference.ToEntity.Name;
            manyToOneNode.name   = directedReference.FromName;
            //bool notNullableColumnsExist = directedRelationship.MappedColumns.Any(mc => !mc.Source.IsNullable);
            manyToOneNode.notnull          = true;
            manyToOneNode.notnullSpecified = true;
            manyToOneNode.fetch            = fetchMode;
            manyToOneNode.fetchSpecified   = true;
            manyToOneNode.insert           = insert;
            manyToOneNode.update           = update;

            ITable         fromPrimaryMappedTable = EntityMapper.GetPrimaryTable(directedReference.FromEntity);
            List <IColumn> fromKeyColumns         = referenceMappedTable.Relationships.First(t => t.PrimaryTable == fromPrimaryMappedTable || t.ForeignTable == fromPrimaryMappedTable).ForeignKey.Columns.ToList();

            if (fromKeyColumns.Count > 1)
            {
                foreach (var columnNode in GetColumnNodes(fromKeyColumns))
                {
                    manyToOneNode.AddColumn(columnNode);
                }
            }
            else
            {
                manyToOneNode.column = fromKeyColumns[0].Name.BackTick();
            }

            return(manyToOneNode);
        }
예제 #8
0
        private static void ProcessOneToManyReference(MappingSet set, Reference reference)
        {
            var manyEnd     = reference.Cardinality1 == Cardinality.Many ? reference.Entity1 : reference.Entity2;
            var directedRef = new DirectedReference(manyEnd, reference);

            var oneEnd       = directedRef.ToEntity;
            var oneEndTable  = oneEnd.MappedTables().First();
            var manyEndTable = manyEnd.MappedTables().First();

            IKey primaryKey = oneEndTable.FirstPrimaryKey;
            // Create a foreign key on the Many side
            Key foreignKey = CreateForeignKey(set, oneEndTable, manyEndTable);

            // Create the relationship between the two.
            var relationship = oneEndTable.CreateRelationshipUsing(primaryKey, foreignKey);

            set.ChangeMappingFor(reference).To(relationship);
        }
        public void It_Creates_The_Right_Relationship()
        {
            var entity1 = mappingSet.EntitySet.GetEntity("BasicClass1");
            var entity2 = mappingSet.EntitySet.GetEntity("BasicClass2");

            Assert.That(entity1.References, Has.Count(1));
            Assert.That(entity2.References, Has.Count(1));

            Assert.That(entity1.References[0], Is.SameAs(entity2.References[0]));

            DirectedReference reference = entity1.DirectedReferences.First();

            Assert.That(reference.FromName, Is.EqualTo("Class2s"));
            Assert.That(reference.ToName, Is.EqualTo("Property1"));
            Assert.That(reference.FromEndCardinality, Is.EqualTo(Cardinality.Many));
            Assert.That(reference.ToEndCardinality, Is.EqualTo(Cardinality.One));
            Assert.That(reference.FromEndEnabled, Is.True);
            Assert.That(reference.ToEndEnabled, Is.True);
        }
예제 #10
0
        private void ProcessOneToOneReference(Entity entity, DirectedReference directedReference, Action <object> addItem, string cascade, string lazy)
        {
            if (directedReference.FromEndEnabled == false)
            {
                return;
            }

            DirectedRelationship directedRelationship = GetDirectedMappedRelationship(entity, directedReference.Reference);

            fetchMode fetchMode;

            if (directedReference.Entity1IsFromEnd)
            {
                fetchMode = (fetchMode)Enum.Parse(typeof(fetchMode), directedReference.Reference.GetReferenceEnd1FetchMode().ToString(), true);
            }
            else
            {
                fetchMode = (fetchMode)Enum.Parse(typeof(fetchMode), directedReference.Reference.GetReferenceEnd2FetchMode().ToString(), true);
            }

            // if this side has the foreign key, it gets the many to one node
            if (directedRelationship.FromKey.Keytype == DatabaseKeyType.Foreign)
            {
                manytoone manyToOneNode = CreateManyToOneNode(directedReference, directedRelationship, cascade);
                manyToOneNode.unique         = true;
                manyToOneNode.fetch          = fetchMode;
                manyToOneNode.fetchSpecified = true;

                addItem(manyToOneNode);
            }
            else
            {
                onetoone oneToOneNode = new onetoone();
                oneToOneNode.@class         = directedReference.ToEntity.Name;
                oneToOneNode.name           = directedReference.FromName;
                oneToOneNode.propertyref    = directedReference.ToName;
                oneToOneNode.fetch          = fetchMode;
                oneToOneNode.fetchSpecified = true;

                addItem(oneToOneNode);
            }
        }
예제 #11
0
        public static string GetIndexColumnTypeName(DirectedReference directedReference, ITable table)
        {
            var columnName = GetIndexColumnName(directedReference);
            var column     = table.GetColumn(columnName, StringComparison.InvariantCultureIgnoreCase);

            if (column == null)
            {
                throw new NHibernateMappingException(string.Format("Could not find the Index Column named {0} for collection {1} on entity {2}", columnName, directedReference.FromName, directedReference.FromEntity.Name));
            }

            ArchAngel.Interfaces.ProjectOptions.TypeMappings.Utility.ColumnInfo columnInfo = new Interfaces.ProjectOptions.TypeMappings.Utility.ColumnInfo()
            {
                IsNullable = column.IsNullable,
                Name       = column.Name,
                Precision  = column.Precision,
                Scale      = column.Scale,
                Size       = column.Size,
                TypeName   = column.OriginalDataType
            };
            return(ArchAngel.Interfaces.ProjectOptions.TypeMappings.Utility.GetCSharpTypeName(column.Parent.Database.DatabaseType.ToString(), columnInfo));
        }
예제 #12
0
        /// <summary>
        /// This method is used in the Template to get the C# Collection type name for the CollectionType of the given reference.
        /// </summary>
        /// <param name="reference"></param>
        /// <returns></returns>
        public static string GetCollectionType(DirectedReference reference)
        {
            switch (GetAssociationType(reference))
            {
            case AssociationType.None:
                //throw new ArgumentException("Reference " + reference.Reference.Name + " does not have an association type for End" + (reference.Entity1IsFromEnd ? "1" : "2"));
                return("XXXXXX");

            case AssociationType.Map:
                // {0} should be the primary key column type, {1} is the entity type.
                //return string.Format("System.Collections.Generic.IDictionary<{0}, {1}>",
                //    GetIndexColumnTypeName(reference, EntityMapper.GetPrimaryTable(reference.FromEntity)),
                //    reference.FromEntity.Name.GetCSharpFriendlyIdentifier());
                return(string.Format("IDictionary<{0}, {1}>",
                                     GetIndexColumnTypeName(reference, EntityMapper.GetPrimaryTable(reference.ToEntity)),
                                     reference.ToEntity.Name));

            case AssociationType.List:
            case AssociationType.Bag:
                //return string.Format("System.Collections.Generic.IList<{0}>", reference.ToEntity.Name.GetCSharpFriendlyIdentifier());
                return(string.Format("IList<{0}>", reference.ToEntity.Name));

            case AssociationType.Set:
                //return string.Format("Iesi.Collections.Generic.ISet<{0}>", reference.ToEntity.Name.GetCSharpFriendlyIdentifier());
                return(string.Format("Iesi.Collections.Generic.ISet<{0}>", reference.ToEntity.Name));

            //case AssociationType.IDBag:
            // Should this also be an IDictionary?
            //    throw new NotImplementedException("Have not implemented IDBag types yet.");
            case AssociationType.IDBag:
                return(string.Format("Iesi.Collections.Generic.ISet<{0}>", reference.ToEntity.Name));

            default:
                throw new NotImplementedException("Collection type not handled yet in GetCollectionType(): " + GetAssociationType(reference));
            }
        }
예제 #13
0
        public static ArchAngel.Providers.EntityModel.Model.DatabaseLayer.IColumn GetIndexColumn(DirectedReference directedReference, ITable table)
        {
            var columnName = GetIndexColumnName(directedReference);

            ArchAngel.Providers.EntityModel.Model.DatabaseLayer.IColumn column = table.GetColumn(columnName, StringComparison.InvariantCultureIgnoreCase);

            if (column == null)
            {
                Property prop = directedReference.ToEntity.Properties.SingleOrDefault(p => p.Name.Equals(columnName, StringComparison.InvariantCultureIgnoreCase));

                if (prop != null)
                {
                    column = prop.MappedColumn();
                }
            }
            return(column);
        }
예제 #14
0
        public static ArchAngel.Interfaces.NHibernateEnums.CascadeTypes GetCascadeType(DirectedReference directedReference)
        {
            string propertyName =
                directedReference.Entity1IsFromEnd ? "Reference_End1Cascade" : "Reference_End2Cascade";

            return((ArchAngel.Interfaces.NHibernateEnums.CascadeTypes)directedReference.Reference.GetUserOptionValue(propertyName));
        }
예제 #15
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());
            }
        }
예제 #16
0
        private manytoone CreateManyToOneNode(DirectedReference directedReference, DirectedRelationship directedRelationship, string cascade)
        {
            fetchMode fetchMode;
            bool      insert;
            bool      update;

            if (directedReference.Entity1IsFromEnd)
            {
                fetchMode = (fetchMode)Enum.Parse(typeof(fetchMode), directedReference.Reference.GetReferenceEnd1FetchMode().ToString(), true);
                insert    = directedReference.Reference.GetReferenceEnd1Insert();
                update    = directedReference.Reference.GetReferenceEnd1Update();
            }
            else
            {
                fetchMode = (fetchMode)Enum.Parse(typeof(fetchMode), directedReference.Reference.GetReferenceEnd2FetchMode().ToString(), true);
                insert    = directedReference.Reference.GetReferenceEnd2Insert();
                update    = directedReference.Reference.GetReferenceEnd2Update();
            }
            manytoone manyToOneNode = new manytoone();

            manyToOneNode.@class = directedReference.ToEntity.Name;
            manyToOneNode.name   = directedReference.FromName;
            bool notNullableColumnsExist = directedRelationship.MappedColumns.Any(mc => !mc.Source.IsNullable);

            manyToOneNode.notnull          = notNullableColumnsExist;
            manyToOneNode.notnullSpecified = true;
            manyToOneNode.fetch            = fetchMode;
            manyToOneNode.fetchSpecified   = true;
            manyToOneNode.insert           = insert;
            manyToOneNode.update           = update;
            manyToOneNode.cascade          = cascade == "none" ? null : cascade;

            if (directedRelationship.ToTable == directedRelationship.FromTable)
            {
                if (directedRelationship.ToKey.Keytype == Providers.EntityModel.Helper.DatabaseKeyType.Primary)
                {
                    if (directedRelationship.FromKey.Columns.Count > 1)
                    {
                        foreach (var column in GetColumnNodes(directedRelationship.FromKey.Columns))
                        {
                            manyToOneNode.AddColumn(column);
                        }
                    }
                    else
                    {
                        manyToOneNode.column = directedRelationship.FromKey.Columns[0].Name.BackTick();
                    }
                }
                else
                if (directedRelationship.ToKey.Columns.Count > 1)
                {
                    foreach (var column in GetColumnNodes(directedRelationship.ToKey.Columns))
                    {
                        manyToOneNode.AddColumn(column);
                    }
                }
                else
                {
                    manyToOneNode.column = directedRelationship.ToKey.Columns[0].Name.BackTick();
                }
            }
            else
            {
                if (directedRelationship.FromKey.Columns.Count > 1)
                {
                    foreach (var column in GetColumnNodes(directedRelationship.FromKey.Columns))
                    {
                        manyToOneNode.AddColumn(column);
                    }
                }
                else
                {
                    manyToOneNode.column = directedRelationship.FromKey.Columns[0].Name.BackTick();
                }
            }
            return(manyToOneNode);
        }
예제 #17
0
        private void ProcessManyToOneReference(
            Entity entity,
            DirectedReference directedReference,
            Action <object> addItem,
            string cascade,
            string collectionCascade,
            string lazy,
            string orderByClause,
            bool inverse)
        {
            if (directedReference.FromEndEnabled == false)
            {
                return;
            }

            ITable referenceMappedTable = directedReference.Reference.MappedTable();
            DirectedRelationship directedRelationship = null;

            if (referenceMappedTable == null)
            {
                directedRelationship = GetDirectedMappedRelationship(entity, directedReference.Reference);
            }

            if (directedReference.FromEndCardinality == Cardinality.One)
            {
                fetchMode fetchMode;
                bool      insert;
                bool      update;

                if (directedReference.Entity1IsFromEnd)
                {
                    fetchMode = (fetchMode)Enum.Parse(typeof(fetchMode), directedReference.Reference.GetReferenceEnd1FetchMode().ToString(), true);
                    insert    = directedReference.Reference.GetReferenceEnd1Insert();
                    update    = directedReference.Reference.GetReferenceEnd1Update();
                }
                else
                {
                    fetchMode = (fetchMode)Enum.Parse(typeof(fetchMode), directedReference.Reference.GetReferenceEnd2FetchMode().ToString(), true);
                    insert    = directedReference.Reference.GetReferenceEnd2Insert();
                    update    = directedReference.Reference.GetReferenceEnd2Update();
                }
                manytoone manyToOneNode;

                if (referenceMappedTable == null)
                {
                    manyToOneNode = CreateManyToOneNode(directedReference, directedRelationship, cascade);
                }
                else
                {
                    manyToOneNode = CreateManyToOneNode(directedReference, referenceMappedTable);
                }

                manyToOneNode.fetch          = fetchMode;
                manyToOneNode.fetchSpecified = true;
                manyToOneNode.insert         = insert;
                manyToOneNode.update         = update;

                addItem(manyToOneNode);
            }
            else
            {
                key keyNode = new key();

                if (referenceMappedTable == null &&
                    directedRelationship.ToKey.Columns.Count > 1)
                {
                    foreach (var columnNode in GetColumnNodes(directedRelationship.ToKey.Columns))
                    {
                        keyNode.AddColumn(columnNode);
                    }
                }
                else if (referenceMappedTable != null)
                {
                    ITable toPrimaryMappedTable  = EntityMapper.GetPrimaryTable(directedReference.ToEntity);
                    var    toColumnsInPrimaryKey = referenceMappedTable.Relationships.First(t => t.PrimaryTable == toPrimaryMappedTable || t.ForeignTable == toPrimaryMappedTable).ForeignKey.Columns;

                    foreach (var columnNode in GetColumnNodes(toColumnsInPrimaryKey))
                    {
                        keyNode.AddColumn(columnNode);
                    }
                }
                else
                {
                    keyNode.column1 = directedRelationship.ToKey.Columns[0].Name.BackTick();
                }

                onetomany oneToManyNode = new onetomany();
                oneToManyNode.@class = directedReference.ToEntity.Name;

                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 ? "1" : "2");
                    return;

                case AssociationType.Set:
                    var set = CreateSetNode(directedReference, keyNode, collectionCascade, collFetchMode, lazy, inverse);
                    set.Item = oneToManyNode;

                    if (orderByClause.Length > 0)
                    {
                        set.orderby = orderByClause;
                    }

                    addItem(set);
                    break;

                case AssociationType.Map:
                    var mapNode = CreateMapNode(directedReference, keyNode, collectionCascade, collFetchMode, lazy, inverse);
                    mapNode.Item = new index
                    {
                        column1 = NHCollections.GetIndexColumnName(directedReference),
                        type    = NHCollections.GetIndexColumnTypeName(directedReference, EntityMapper.GetPrimaryTable(directedReference.ToEntity))
                    };
                    mapNode.Item1 = oneToManyNode;

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

                    addItem(mapNode);
                    break;

                case AssociationType.Bag:
                    var bag = CreateBagNode(directedReference, keyNode, collectionCascade, collFetchMode, lazy, inverse);
                    bag.Item = oneToManyNode;

                    if (orderByClause.Length > 0)
                    {
                        bag.orderby = orderByClause;
                    }

                    addItem(bag);
                    break;

                case AssociationType.List:
                    list listNode = CreateListNode(directedReference, keyNode, collectionCascade, collFetchMode, lazy, inverse);
                    listNode.Item = new index {
                        column1 = NHCollections.GetIndexColumnName(directedReference)
                    };
                    listNode.Item1 = oneToManyNode;

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

                    addItem(listNode);
                    break;

                case AssociationType.IDBag:
                    idbag idbagNode = CreateIdBagNode(directedReference, keyNode, collectionCascade, collFetchMode, lazy, inverse);
                    idbagNode.collectionid = new collectionid
                    {
                        column1   = NHCollections.GetIndexColumnName(directedReference),
                        generator = new generator {
                            @class = "sequence"
                        },
                        type = NHCollections.GetIndexColumnTypeName(directedReference, EntityMapper.GetPrimaryTable(directedReference.ToEntity))
                    };

                    addItem(idbagNode);
                    break;

                default:
                    throw new ArgumentOutOfRangeException("AssociationType not handled yet: " + type.ToString());
                }
            }
        }