private IDictionary <ObjectID, ILoadedObjectData> CorrelateRelatedObjects(
            IEnumerable <LoadedObjectDataWithDataSourceData> relatedObjects,
            VirtualRelationEndPointDefinition relationEndPointDefinition)
        {
            var relatedObjectsWithForeignKey = GetForeignKeysForVirtualEndPointDefinition(relatedObjects, relationEndPointDefinition);
            var dictionary = new Dictionary <ObjectID, ILoadedObjectData>();

            foreach (var tuple in relatedObjectsWithForeignKey.Where(tuple => tuple.Item1 != null))
            {
                try
                {
                    dictionary.Add(tuple.Item1, tuple.Item2.LoadedObjectData);
                }
                catch (ArgumentException ex)
                {
                    var message = string.Format(
                        "Two items in the related object result set point back to the same object. This is not allowed in a 1:1 relation. "
                        + "Object 1: '{0}'. Object 2: '{1}'. Foreign key property: '{2}'",
                        dictionary[tuple.Item1].ObjectID,
                        tuple.Item2.LoadedObjectData.ObjectID,
                        relationEndPointDefinition.GetOppositeEndPointDefinition().PropertyName);
                    throw new InvalidOperationException(message, ex);
                }
            }
            return(dictionary);
        }
        protected IEnumerable <Tuple <ObjectID, LoadedObjectDataWithDataSourceData> > GetForeignKeysForVirtualEndPointDefinition(
            IEnumerable <LoadedObjectDataWithDataSourceData> loadedObjectData,
            VirtualRelationEndPointDefinition virtualEndPointDefinition)
        {
            ArgumentUtility.CheckNotNull("loadedObjectData", loadedObjectData);
            ArgumentUtility.CheckNotNull("virtualEndPointDefinition", virtualEndPointDefinition);

            var oppositeEndPointDefinition = (RelationEndPointDefinition)virtualEndPointDefinition.GetOppositeEndPointDefinition();

            return(from data in loadedObjectData
                   where !data.IsNull
                   let dataContainer = CheckRelatedObjectAndGetDataContainer(
                       data,
                       virtualEndPointDefinition,
                       oppositeEndPointDefinition)
                                       let originatingObjectID = (ObjectID)dataContainer.GetValueWithoutEvents(oppositeEndPointDefinition.PropertyDefinition, ValueAccess.Current)
                                                                 select Tuple.Create(originatingObjectID, data));
        }
        private DataContainerCollection LoadOppositeDataContainers(
            RelationEndPointID relationEndPointID, VirtualRelationEndPointDefinition virtualEndPointDefinition)
        {
            var oppositeEndPointDefinition = virtualEndPointDefinition.GetOppositeEndPointDefinition();
            var oppositeProvider           =
                _storageProviderManager.GetMandatory(oppositeEndPointDefinition.ClassDefinition.StorageEntityDefinition.StorageProviderDefinition.Name);

            var oppositeDataContainers = oppositeProvider.LoadDataContainersByRelatedID(
                (RelationEndPointDefinition)oppositeEndPointDefinition,
                virtualEndPointDefinition.GetSortExpression(),
                relationEndPointID.ObjectID);

            var oppositeDataContainerCollection = new DataContainerCollection();

            foreach (var oppositeDataContainer in oppositeDataContainers)
            {
                CheckClassIDForVirtualEndPoint(relationEndPointID, oppositeDataContainer);
                oppositeDataContainerCollection.Add(oppositeDataContainer);
            }
            return(oppositeDataContainerCollection);
        }