/// <summary>
        /// Serializes this <see cref="T:ORMSolutions.ORMArchitect.Views.RelationalView.RelationalDiagram"/>.
        /// </summary>
        /// <param name="writer">A <see cref="T:System.Xml.XmlWriter"/> that will write the custom serialization contents.</param>
        void IXmlSerializable.WriteXml(XmlWriter writer)
        {
            string rvNamespace = RelationalShapeDomainModel.XmlNamespace;
            // <RelationalDiagram>
            //    <TableShape ObjectTypeRef="" Location="x, y" />
            //    ...
            // </RelationalDiagram>
            ISerializationContext serializationContext = ((ISerializationContextHost)Store).SerializationContext;

            writer.WriteStartElement(RelationalDiagramElementName, rvNamespace);
            writer.WriteAttributeString(IdAttributeName, serializationContext.GetIdentifierString(Id));
            writer.WriteAttributeString(DisplayDataTypesAttributeName, XmlConvert.ToString(DisplayDataTypes));
            writer.WriteAttributeString(SubjectRefAttributeName, serializationContext.GetIdentifierString(this.ModelElement.Id));
            TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(PointD));

            foreach (ShapeElement shapeElement in this.NestedChildShapes)
            {
                TableShape tableShape = shapeElement as TableShape;
                if (tableShape != null)
                {
                    ConceptType conceptType;
                    ObjectType  objectType;
                    if (null != (conceptType = TableIsPrimarilyForConceptType.GetConceptType((Table)tableShape.ModelElement)) &&
                        null != (objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType)))
                    {
                        writer.WriteStartElement(TableShapeElementName, rvNamespace);
                        writer.WriteAttributeString(ObjectTypeRefAttributeName, serializationContext.GetIdentifierString(objectType.Id));
                        writer.WriteAttributeString(LocationAttributeName, typeConverter.ConvertToInvariantString(tableShape.Location));
                        writer.WriteEndElement();
                    }
                }
            }
            writer.WriteEndElement();
        }
示例#2
0
 private static void ValidateReferenceModeNamingChanged(ReferenceModeNamingCustomizesObjectType referenceModeNamingCustomizesObjectType)
 {
     if (null != referenceModeNamingCustomizesObjectType)
     {
         ORMCore.ObjectType objectType = referenceModeNamingCustomizesObjectType.ObjectType;
         if (objectType != null)
         {
             ConceptType conceptType = ConceptTypeIsForObjectType.GetConceptType(objectType);
             if (null == conceptType)
             {
                 foreach (ORMCore.Role role in objectType.PlayedRoleCollection)
                 {
                     foreach (ConceptTypeChild conceptTypeChild in ConceptTypeChildHasPathFactType.GetConceptTypeChild(role.FactType))
                     {
                         ValidateConceptTypeChildNameChanged(conceptTypeChild);
                     }
                 }
             }
             else
             {
                 ValidateConceptTypeNameChanged(conceptType);
             }
         }
     }
 }
        /// <summary>
        /// Customize childshape create to set an initial location for a <see cref="TableShape"/>
        /// </summary>
        protected override ShapeElement CreateChildShape(ModelElement element)
        {
            object tablePositionsObject;
            Dictionary <Guid, PointD> tablePositions;
            PointD initialLocation;
            ReferenceConstraintTargetsTable referenceConstraintTargetsTable;
            Table       table;
            ConceptType conceptType;
            ObjectType  objectType;

            if (null != (table = element as Table))
            {
                if (element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo.TryGetValue(TablePositionDictionaryKey, out tablePositionsObject) &&
                    null != (tablePositions = tablePositionsObject as Dictionary <Guid, PointD>) &&
                    null != (conceptType = TableIsPrimarilyForConceptType.GetConceptType(table)) &&
                    null != (objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType)) &&
                    tablePositions.TryGetValue(objectType.Id, out initialLocation))
                {
                    return(new TableShape(
                               this.Partition,
                               new PropertyAssignment(TableShape.AbsoluteBoundsDomainPropertyId, new RectangleD(initialLocation, new SizeD(1, 0.3)))));
                }
            }
            else if (null != (referenceConstraintTargetsTable = element as ReferenceConstraintTargetsTable))
            {
                return(new ForeignKeyConnector(Partition));
            }
            return(base.CreateChildShape(element));
        }
示例#4
0
        /// <summary>
        /// Customize childshape create to set an initial location for a <see cref="BarkerEntityShape"/>
        /// </summary>
        protected override ShapeElement CreateChildShape(ModelElement element)
        {
            object barkerEntityPositionsObject;
            Dictionary <Guid, PointD> barkerEntityPositions;
            PointD initialLocation;
            BarkerErModelContainsBinaryAssociation modelContainsAssociation;
            EntityType  barkerEntity;
            ConceptType conceptType;
            ObjectType  objectType;

            if (null != (barkerEntity = element as EntityType))
            {
                if (element.Store.TransactionManager.CurrentTransaction.TopLevelTransaction.Context.ContextInfo.TryGetValue(BarkerEntityPositionDictionaryKey, out barkerEntityPositionsObject) &&
                    null != (barkerEntityPositions = barkerEntityPositionsObject as Dictionary <Guid, PointD>) &&
                    null != (conceptType = EntityTypeIsPrimarilyForConceptType.GetConceptType(barkerEntity)) &&
                    null != (objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType)) &&
                    barkerEntityPositions.TryGetValue(objectType.Id, out initialLocation))
                {
                    return(new BarkerEntityShape(
                               this.Partition,
                               new PropertyAssignment(BarkerEntityShape.AbsoluteBoundsDomainPropertyId, new RectangleD(initialLocation, new SizeD(1, 0.3)))));
                }
            }
            else if (null != (modelContainsAssociation = element as BarkerErModelContainsBinaryAssociation))
            {
                return(new AssociationConnector(Partition));
            }
            return(base.CreateChildShape(element));
        }
示例#5
0
 private static void UpdateNamesForObjectTypeDelayed(ModelElement element)
 {
     if (!element.IsDeleted)
     {
         ObjectType  objectType     = (ObjectType)element;
         string      objectTypeName = objectType.Name;
         ConceptType conceptType    = ConceptTypeIsForObjectType.GetConceptType(objectType);
         LinkedElementCollection <FactType> pathFactTypes;
         int      factTypeCount;
         RoleBase towardsRole;
         RoleBase oppositeRole;
         if (null != conceptType)
         {
             // Precheck name to minimize downstream calls, the property change
             // will check itself.
             if (conceptType.Name != objectTypeName)
             {
                 conceptType.Name = objectTypeName;
                 foreach (ConceptTypeReferencesConceptType reference in ConceptTypeReferencesConceptType.GetLinksToReferencingConceptTypeCollection(conceptType))
                 {
                     pathFactTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(reference);
                     if (0 != (factTypeCount = pathFactTypes.Count) &&
                         null != (towardsRole = FactTypeMapsTowardsRole.GetTowardsRole(pathFactTypes[factTypeCount - 1])) &&
                         null != (oppositeRole = towardsRole.OppositeRole))
                     {
                         reference.OppositeName = ResolveRoleName(oppositeRole);
                     }
                 }
                 foreach (ConceptTypeReferencesConceptType reference in ConceptTypeReferencesConceptType.GetLinksToReferencedConceptTypeCollection(conceptType))
                 {
                     pathFactTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(reference);
                     if (0 != (factTypeCount = pathFactTypes.Count) &&
                         null != (towardsRole = FactTypeMapsTowardsRole.GetTowardsRole(pathFactTypes[factTypeCount - 1])))
                     {
                         reference.Name = ResolveRoleName(towardsRole);
                     }
                 }
             }
         }
         InformationTypeFormat informationTypeFormat = InformationTypeFormatIsForValueType.GetInformationTypeFormat(objectType);
         if (null != informationTypeFormat)
         {
             if (informationTypeFormat.Name != objectTypeName)
             {
                 informationTypeFormat.Name = objectTypeName;
                 foreach (InformationType informationType in InformationType.GetLinksToConceptTypeCollection(informationTypeFormat))
                 {
                     pathFactTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(informationType);
                     if (0 != (factTypeCount = pathFactTypes.Count) &&
                         null != (towardsRole = FactTypeMapsTowardsRole.GetTowardsRole(pathFactTypes[factTypeCount - 1])) &&
                         null != (oppositeRole = towardsRole.OppositeRole))
                     {
                         informationType.Name = ResolveRoleName(oppositeRole);
                     }
                 }
             }
         }
     }
 }
            /// <summary>
            /// Make sure we have our tracker attached to all loaded models.
            /// </summary>
            /// <param name="element">An ORMModel element</param>
            /// <param name="store">The context store</param>
            /// <param name="notifyAdded">The listener to notify if elements are added during fixup</param>
            protected sealed override void ProcessElement(ORMModel element, Store store, INotifyElementAdded notifyAdded)
            {
                AbstractionModel oil = AbstractionModelIsForORMModel.GetAbstractionModel(element);

                if (oil == null)
                {
                    // UNDONE: DelayValidateModel currently deletes and recreates any existing
                    // bridge relationship, so there is no point deleting it up front, we'll
                    // just retrieve it later. Also note that DelayValidateModel does not call notifyAdded.
                    DelayValidateModel(element);
                    oil = AbstractionModelIsForORMModel.GetAbstractionModel(element);
                    if (oil != null)
                    {
                        notifyAdded.ElementAdded(oil, true);
                    }
                }
                else
                {
                    AbstractionModelGenerationSetting generationSetting;
                    bool regenerateForVersion   = null == (generationSetting = GenerationSettingTargetsAbstractionModel.GetGenerationSetting(oil)) || generationSetting.AlgorithmVersion != CurrentAlgorithmVersion;
                    bool excludedBridgedElement = false;
                    ORMElementGateway.Initialize(
                        element,
                        regenerateForVersion ? (ORMElementGateway.NotifyORMElementExcluded) null :
                        delegate(ORMModelElement modelElement)
                    {
                        if (excludedBridgedElement)
                        {
                            return;
                        }
                        ObjectType objectType;
                        FactType factType;
                        // Note that the types we're checking here are synchronized with the ORMElementGateway.ExclusionAdded method
                        if (null != (objectType = modelElement as ObjectType))
                        {
                            if (null != ConceptTypeIsForObjectType.GetLinkToConceptType(objectType) ||
                                null != InformationTypeFormatIsForValueType.GetLinkToInformationTypeFormat(objectType))
                            {
                                excludedBridgedElement = true;
                            }
                        }
                        else if (null != (factType = modelElement as FactType))
                        {
                            if (null != FactTypeMapsTowardsRole.GetLinkToTowardsRole(factType) ||
                                ConceptTypeChildHasPathFactType.GetLinksToConceptTypeChild(factType).Count != 0)
                            {
                                excludedBridgedElement = true;
                            }
                        }
                    });
                    if (regenerateForVersion || excludedBridgedElement)
                    {
                        // Something is very wrong, regenerate (does not regenerate the excluded elements we already have)
                        DelayValidateModel(element);
                    }
                }
            }
示例#7
0
        /// <summary>
        /// DeletingRule: typeof(ORMSolutions.ORMArchitect.ORMAbstractionToBarkerERBridge.EntityTypeIsPrimarilyForConceptType)
        /// Cache the position of the <see cref="BarkerEntityShape"/> corresponding to the object type being deleted
        /// </summary>
        private static void ConceptTypeDetachingFromEntityTypeRule(ElementDeletingEventArgs e)
        {
            EntityTypeIsPrimarilyForConceptType link = (EntityTypeIsPrimarilyForConceptType)e.ModelElement;
            ObjectType objectType;

            if (null != (objectType = ConceptTypeIsForObjectType.GetObjectType(link.ConceptType)) &&
                !objectType.IsDeleting)
            {
                RememberBarkerEntityShapeLocations(objectType, link.EntityType);
            }
        }
示例#8
0
        /// <summary>
        /// DeletingRule: typeof(ORMSolutions.ORMArchitect.ORMToORMAbstractionBridge.ConceptTypeIsForObjectType)
        /// Cache the position of the <see cref="BarkerEntityShape"/> corresponding to the object type being deleted
        /// </summary>
        private static void ConceptTypeDetachingFromObjectTypeRule(ElementDeletingEventArgs e)
        {
            ConceptTypeIsForObjectType link = (ConceptTypeIsForObjectType)e.ModelElement;
            ObjectType objectType           = link.ObjectType;
            EntityType barkerEntity;

            if (!objectType.IsDeleting &&
                null != (barkerEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(link.ConceptType)))
            {
                RememberBarkerEntityShapeLocations(objectType, barkerEntity);
            }
        }
示例#9
0
        /// <summary>
        /// DeletingRule: typeof(ORMSolutions.ORMArchitect.ORMToORMAbstractionBridge.ConceptTypeIsForObjectType)
        /// Cache the position of the <see cref="TableShape"/> corresponding to the object type being deleted
        /// </summary>
        private static void ConceptTypeDetachingFromObjectTypeRule(ElementDeletingEventArgs e)
        {
            ConceptTypeIsForObjectType link = (ConceptTypeIsForObjectType)e.ModelElement;
            ObjectType objectType           = link.ObjectType;
            Table      table;

            if (!objectType.IsDeleting &&
                null != (table = TableIsPrimarilyForConceptType.GetTable(link.ConceptType)))
            {
                RememberTableShapeLocations(objectType, table);
            }
        }
        private bool GetTableKey(Table table, out Guid key)
        {
            ConceptType conceptType;
            ObjectType  objectType;

            if (null != (conceptType = TableIsPrimarilyForConceptType.GetConceptType(table)) &&
                null != (objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType)))
            {
                key = objectType.Id;
                return(true);
            }
            key = Guid.Empty;
            return(false);
        }
示例#11
0
        /// <summary>
        /// Implements <see cref="IVerbalize.GetVerbalization"/>
        /// </summary>
        protected bool GetVerbalization(TextWriter writer, IDictionary <Type, IVerbalizationSets> snippetsDictionary, IVerbalizationContext verbalizationContext, VerbalizationSign sign)
        {
            // We are redirected to this point by the associated Table element
            ConceptType conceptType = this.ConceptType;
            ObjectType  objectType;

            if (null != (objectType = ConceptTypeIsForObjectType.GetObjectType(conceptType)))
            {
                verbalizationContext.DeferVerbalization(objectType, DeferVerbalizationOptions.None, null);
                foreach (ConceptType alsoForConceptType in TableIsAlsoForConceptType.GetConceptType(this.Table))
                {
                    if (null != (objectType = ConceptTypeIsForObjectType.GetObjectType(alsoForConceptType)))
                    {
                        writer.WriteLine();
                        verbalizationContext.DeferVerbalization(objectType, DeferVerbalizationOptions.None, null);
                    }
                }
            }
            return(false);
        }
        /// <summary>
        /// Get a minimal unique identifier for a column based on mapped roles. The identifer
        /// will stop as soon as the fact type is used in a single column or in a partitioned
        /// or separated column.
        /// </summary>
        /// <param name="column">The <see cref="Column"/> to analyze</param>
        /// <param name="idList">Scratch list used to determine keys</param>
        /// <param name="minKeySize">The minimum number of ids that uniquely
        /// identify this column. The actually key may be longer than this
        /// minimimum for partitioned and separated tables. Key comparisons
        /// may be performed down to this minimum size.</param>
        /// <returns><see langword="true"/> if the key was available.</returns>
        private static bool BuildKey(Column column, List <Guid> idList, out int minKeySize)
        {
            idList.Clear();
            int uniqueUseIndex = -1;

            minKeySize = 0;
            LinkedElementCollection <ConceptTypeChild> childNodes = ColumnHasConceptTypeChild.GetConceptTypeChildPath(column);

            for (int i = childNodes.Count - 1; i >= 0; --i)
            {
                ConceptTypeChild child       = childNodes[i];
                bool             uniqueChild = ColumnHasConceptTypeChild.GetLinksToColumn(child).Count == 1;
                LinkedElementCollection <FactType> pathFactTypes = ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(child);
                int             factTypeCount = pathFactTypes.Count;
                InformationType infoType;
                ObjectType      objectType;
                if (0 != (factTypeCount = pathFactTypes.Count))
                {
                    for (int j = factTypeCount - 1; j >= 0; --j)
                    {
                        FactType factType = pathFactTypes[j];
                        idList.Add(FactTypeMapsTowardsRole.GetTowardsRole(factType).Id);
                        if (-1 == uniqueUseIndex &&
                            uniqueChild &&
                            ConceptTypeChildHasPathFactType.GetLinksToConceptTypeChild(factType).Count == 1)
                        {
                            minKeySize     = idList.Count;
                            uniqueUseIndex = minKeySize - 1;
                        }
                    }
                    ConceptTypeAssimilatesConceptType assimilation;
                    if (uniqueUseIndex != -1 &&
                        null != (assimilation = child as ConceptTypeAssimilatesConceptType) &&
                        AssimilationMapping.GetAbsorptionChoiceFromAssimilation(assimilation) != AssimilationAbsorptionChoice.Absorb)
                    {
                        uniqueUseIndex = idList.Count - 1;
                    }
                }
                else if (null != (infoType = child as InformationType) &&
                         null != (objectType = ConceptTypeIsForObjectType.GetObjectType(infoType.ConceptType)))
                {
                    // Happens for a value column in an object type table, which has one concept type child
                    idList.Add(objectType.Id);
                }
            }
            int count = idList.Count;

            if (0 == count)
            {
                return(false);
            }
            if (uniqueUseIndex != -1 &&
                (uniqueUseIndex + 1) < count)
            {
                idList.RemoveRange(uniqueUseIndex + 1, count - uniqueUseIndex - 1);
            }
            if (minKeySize == 0)
            {
                minKeySize = idList.Count;
            }
            return(true);
        }
示例#13
0
		/// <summary>
		/// Generages the <see cref="ConceptType"/> objects along with any relationships that they have and adds them to the
		/// model.
		/// </summary>
		/// <param name="factTypeMappings">A dictionary of all the final decided FactTypeMapping objects.</param>
		private void GenerateConceptTypes(FactTypeMappingDictionary factTypeMappings)
		{
			ORMModel model = this.ORMModel;
			LinkedElementCollection<ObjectType> modelObjectTypes = model.ObjectTypeCollection;
			AbstractionModel oialModel = this.AbstractionModel;

			// For each object type in the model...
			foreach (ObjectType objectType in modelObjectTypes)
			{
				if (ShouldIgnoreObjectType(objectType))
				{
					continue;
				}
				// If it should have a conctpt type...
				if (ObjectTypeIsConceptType(objectType, factTypeMappings))
				{
					// Create the ConceptType object.
					PropertyAssignment name = new PropertyAssignment(ConceptType.NameDomainPropertyId, objectType.Name);
					ConceptType conceptType = new ConceptType(Store, name);
					ConceptTypeIsForObjectType conceptTypeIsForObjectType = new ConceptTypeIsForObjectType(conceptType, objectType);

					// Add it to the model.
					oialModel.ConceptTypeCollection.Add(conceptType);

					// If this conceptType is for a ValueType...
					if (objectType.IsValueType)
					{
						InformationTypeFormat valueTypeInformationTypeFormat = InformationTypeFormatIsForValueType.GetInformationTypeFormat(objectType);

						RoleAssignment conceptTypeRole = new RoleAssignment(InformationType.ConceptTypeDomainRoleId, conceptType);
						RoleAssignment informationTypeFormat = new RoleAssignment(InformationType.InformationTypeFormatDomainRoleId, valueTypeInformationTypeFormat);
						RoleAssignment[] roleAssignments = { conceptTypeRole, informationTypeFormat };
						PropertyAssignment isMandatory = new PropertyAssignment(InformationType.IsMandatoryDomainPropertyId, true);
						PropertyAssignment informationTypeNameProperty = new PropertyAssignment(InformationType.NameDomainPropertyId, String.Concat(objectType.Name, "Value"));
						PropertyAssignment[] informationTypePropertyAssignments = { isMandatory, informationTypeNameProperty };

						// ConceptType for conceptType gets an InformationType that references InformationTypeFormat for conceptType.
						InformationType informationType = new InformationType(Store, roleAssignments, informationTypePropertyAssignments);

						PropertyAssignment uniquenessNameProperty = new PropertyAssignment(Uniqueness.NameDomainPropertyId, String.Concat(objectType.Name, "Uniqueness"));
						PropertyAssignment isPreferred = new PropertyAssignment(Uniqueness.IsPreferredDomainPropertyId, true);
						PropertyAssignment[] uniquenessPropertyAssignments = { uniquenessNameProperty, isPreferred };

						// Uniqueness constraint
						Uniqueness uniqueness = new Uniqueness(Store, uniquenessPropertyAssignments);
						UniquenessIncludesConceptTypeChild uniquenessIncludesConceptTypeChild = new UniquenessIncludesConceptTypeChild(uniqueness, informationType);

						conceptType.UniquenessCollection.Add(uniqueness);
					}
				}
			}
		}
        /// <summary>
        /// for regular relationships
        /// </summary>
        /// <param name="relation"></param>
        /// <param name="source"></param>
        /// <param name="target"></param>
        /// <param name="notifyAdded"></param>
        /// <param name="associationCounter"></param>
        /// <returns></returns>
        private static bool CreateBinaryAssociation(ConceptTypeChild relation, ConceptType source, ConceptType target, INotifyElementAdded notifyAdded, ref int associationCounter)
        {
            if (BinaryAssociationHasConceptTypeChild.GetBinaryAssociation(relation).Count > 0)
            {
                //it has already been created
                return(true);
            }
            else if (EntityTypeIsPrimarilyForConceptType.GetEntityType(target) != null)
            {
                #region create association
                BinaryAssociation b = new BinaryAssociation(relation.Store,
                                                            new PropertyAssignment[] { new PropertyAssignment(BinaryAssociation.NumberDomainPropertyId, associationCounter++) });
                //new BinaryAssociationHasConceptTypeChild(b, relation);
                BinaryAssociationHasConceptTypeChild.GetConceptTypeChildPath(b).Add(relation);

                Role r1 = new Role(relation.Store,
                                   new PropertyAssignment[] { new PropertyAssignment(Role.PredicateTextDomainPropertyId, source.Name) });

                Role r2 = new Role(relation.Store,
                                   new PropertyAssignment[] { new PropertyAssignment(Role.PredicateTextDomainPropertyId, target.Name) });

                b.RoleCollection.Add(r1);
                b.RoleCollection.Add(r2);

                EntityType sourceEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(source);
                EntityType targetEntity = EntityTypeIsPrimarilyForConceptType.GetEntityType(target);
                sourceEntity.RoleCollection.Add(r1);
                targetEntity.RoleCollection.Add(r2);
                sourceEntity.BarkerErModel.BinaryAssociationCollection.Add(b);
                #endregion

                //determine whether roles are mandatory or optional
                List <ConceptTypeChild> links = new List <ConceptTypeChild>(1);
                links.Add(relation);
                r1.IsMandatory = AllStepsMandatory(targetEntity, links);
                if (relation is ConceptTypeAssimilatesConceptType)
                {
                    r2.IsMandatory = AllStepsMandatory(sourceEntity, links);
                }

                #region determine whether roles are multivalued or not - and possibly rename
                ORMCore.ObjectType           sourceObjectType = ConceptTypeIsForObjectType.GetObjectType(source);
                ORMCore.ObjectType           targetObjectType = ConceptTypeIsForObjectType.GetObjectType(target);
                ORMCore.UniquenessConstraint uSource = null, uTarget = null;
                foreach (ORMCore.FactType factType in ConceptTypeChildHasPathFactType.GetPathFactTypeCollection(relation))
                {
                    Debug.Assert(factType.RoleCollection.Count == 2, "Error when mapping to Barker ER; the fact type is not binary");
                    foreach (ORMCore.RoleBase r in factType.RoleCollection)
                    {
                        //need to use RoleBase because we might run into RoleProxy
                        ORMCore.Role role = r.Role;
                        foreach (ORMCore.ConstraintRoleSequence constraintRoleSequence in role.ConstraintRoleSequenceCollection)
                        {
                            ORMCore.UniquenessConstraint uninquenessConstraint = constraintRoleSequence as ORMCore.UniquenessConstraint;
                            if (uninquenessConstraint != null &&                                        //check that it's a uniqueness constraint
                                uninquenessConstraint.Modality == ORMCore.ConstraintModality.Alethic && //check it's alethic
                                uninquenessConstraint.IsInternal)                                       //check it's internal
                            {
                                if (role.RolePlayer == sourceObjectType)
                                {
                                    uSource = uninquenessConstraint;
                                }
                                if (role.RolePlayer == targetObjectType)
                                {
                                    uTarget = uninquenessConstraint;
                                }
                            }
                        }
                    }
                    //name the roles properly
                    //TODO this is a hack; proper name generation is yet to be implemented
                    foreach (ORMCore.ReadingOrder order in factType.ReadingOrderCollection)
                    {
                        string text  = order.ReadingText;
                        int    first = text.IndexOf('}') + 1;
                        text = text.Substring(first, text.LastIndexOf('{') - first);
                        text = text.Trim();

                        if (!string.IsNullOrEmpty(text) &&
                            order.RoleCollection != null && order.RoleCollection.Count > 0 &&
                            order.RoleCollection[0].Role != null)
                        {
                            ORMCore.ObjectType o = order.RoleCollection[0].Role.RolePlayer;
                            if (o == sourceObjectType)
                            {
                                r1.PredicateText = text;
                            }
                            else if (o == targetObjectType)
                            {
                                r2.PredicateText = text;
                            }
                        }
                    }
                }
                if (uSource != null && uSource == uTarget)
                {
                    //it's many-to-many
                    r1.IsMultiValued = true;
                    r2.IsMultiValued = true;
                }
                else if (uSource == null || uTarget == null)
                {
                    //it's one-to-many
                    r1.IsMultiValued = uSource != null;
                    r2.IsMultiValued = uTarget != null;
                }
                else if (uSource != null && uTarget != null)
                {
                    //it's one-to-one
                    r1.IsMultiValued = false;
                    r2.IsMultiValued = false;
                }
                else
                {
                    Debug.Fail("Found a fact type with no uniqueness constraints!");
                }
                #endregion

                #region primary id?
                foreach (Uniqueness u in UniquenessIncludesConceptTypeChild.GetUniquenessCollection(relation))
                {
                    if (u.IsPreferred)
                    {
                        r1.IsPrimaryIdComponent = true;
                        break;
                    }
                }
                #endregion

                //notify elements added
                if (notifyAdded != null)
                {
                    notifyAdded.ElementAdded(b, true);
                    notifyAdded.ElementAdded(r1, true);
                    notifyAdded.ElementAdded(r2, true);
                }

                return(true);
            }
            else
            {
                //should not create binary association in this case
                return(false);
            }
        }