Пример #1
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());
                }
            }
        }
Пример #2
0
        public IValidationResult Run(MappingSet set)
        {
            IValidationResult result = new ValidationResult(this);

            foreach (var reference in set.EntitySet.Entities.SelectMany(e => e.References).Distinct())
            {
                var mappedTable = reference.MappedTable();

                if (reference.Cardinality1 == ArchAngel.Interfaces.Cardinality.Many &&
                    reference.Cardinality2 == ArchAngel.Interfaces.Cardinality.Many)
                {
                    if (mappedTable == null)
                    {
                        result.Issues.Add(new ValidationIssue(string.Format("Reference [{0} to {1}] with many-to-many collection type is missing an Association Table.", reference.Entity1.Name, reference.Entity2.Name), reference, ValidationErrorLevel.Error));
                    }
                    else
                    {
                        // Check that columns exist and match for the mapped table.
                        var primaryTable1 = ArchAngel.NHibernateHelper.MappingFiles.Version_2_2.EntityMapper.GetPrimaryTable(reference.Entity1);
                        var primaryTable2 = ArchAngel.NHibernateHelper.MappingFiles.Version_2_2.EntityMapper.GetPrimaryTable(reference.Entity2);

                        if (mappedTable.Relationships.Where(t => t.PrimaryTable == primaryTable1).Count() == 0)
                        {
                            result.Issues.Add(new ValidationIssue(string.Format("Reference [{0} to {1}] with many-to-many collection type is missing an Association Table.", reference.Entity1.Name, reference.Entity2.Name), reference, ValidationErrorLevel.Error));
                        }

                        if (mappedTable.Relationships.Where(t => t.PrimaryTable == primaryTable2).Count() == 0)
                        {
                            result.Issues.Add(new ValidationIssue(string.Format("Reference [{0} to {1}] with many-to-many collection type is missing an Association Table.", reference.Entity1.Name, reference.Entity2.Name), reference, ValidationErrorLevel.Error));
                        }
                    }
                }
                else if (reference.MappedRelationship() == null && mappedTable == null)
                {
                    result.Issues.Add(new ValidationIssue(string.Format("Reference [{0} to {1}] is missing a Mapped Relationship or Association Table.", reference.Entity1.Name, reference.Entity2.Name), reference, ValidationErrorLevel.Error));
                }
            }
            foreach (var directedReference in set.EntitySet.Entities.SelectMany(e => e.DirectedReferences).Distinct())
            {
                var collectionType = (ArchAngel.Interfaces.Scripting.NHibernate.Model.CollectionTypes)Enum.Parse(typeof(ArchAngel.Interfaces.Scripting.NHibernate.Model.CollectionTypes), NHCollections.GetAssociationType(directedReference).ToString(), true);

                if (collectionType == ArchAngel.Interfaces.Scripting.NHibernate.Model.CollectionTypes.Map ||
                    collectionType == ArchAngel.Interfaces.Scripting.NHibernate.Model.CollectionTypes.IDBag ||
                    collectionType == ArchAngel.Interfaces.Scripting.NHibernate.Model.CollectionTypes.List)
                {
                    var indexColumn = NHCollections.GetIndexColumn(directedReference, ArchAngel.NHibernateHelper.MappingFiles.Version_2_2.EntityMapper.GetPrimaryTable(directedReference.ToEntity));

                    if (indexColumn == null)
                    {
                        result.Issues.Add(new ValidationIssue(string.Format("'{0}' collection [{1} to {2}] has an invalid index column specified.",
                                                                            collectionType.ToString(),
                                                                            directedReference.FromEntity.Name,
                                                                            directedReference.ToEntity.Name), directedReference.Reference, ValidationErrorLevel.Error));
                    }
                    //newReference.CollectionIndexColumn = columnLookups[NHCollections.GetIndexColumn(directedReference, ArchAngel.NHibernateHelper.MappingFiles.Version_2_2.EntityMapper.GetPrimaryTable(directedReference.FromEntity))];
                }
                //else if (collectionType == Interfaces.Scripting.NHibernate.Model.CollectionTypes.None &&
                //    directedReference.FromEndCardinality == ArchAngel.Interfaces.Cardinality.Many)
                //{
                //    result.Issues.Add(new ValidationIssue(string.Format("No collection type has been set for the reference between {1} and {2}.",
                //        collectionType.ToString(),
                //        directedReference.FromEntity.Name,
                //        directedReference.ToEntity.Name), directedReference.Reference, ValidationErrorLevel.Error));
                //}
            }
            return(result);
        }
Пример #3
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());
            }
        }