internal DbRelatedEntityRef(
            RelationshipEndMember sourceEnd,
            RelationshipEndMember targetEnd,
            DbExpression targetEntityRef)
        {
            if (!object.ReferenceEquals((object)sourceEnd.DeclaringType, (object)targetEnd.DeclaringType))
            {
                throw new ArgumentException(Strings.Cqt_RelatedEntityRef_TargetEndFromDifferentRelationship, nameof(targetEnd));
            }
            if (object.ReferenceEquals((object)sourceEnd, (object)targetEnd))
            {
                throw new ArgumentException(Strings.Cqt_RelatedEntityRef_TargetEndSameAsSourceEnd, nameof(targetEnd));
            }
            if (targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.One && targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne)
            {
                throw new ArgumentException(Strings.Cqt_RelatedEntityRef_TargetEndMustBeAtMostOne, nameof(targetEnd));
            }
            if (!TypeSemantics.IsReferenceType(targetEntityRef.ResultType))
            {
                throw new ArgumentException(Strings.Cqt_RelatedEntityRef_TargetEntityNotRef, nameof(targetEntityRef));
            }
            EntityTypeBase elementType1 = TypeHelpers.GetEdmType <RefType>(targetEnd.TypeUsage).ElementType;
            EntityTypeBase elementType2 = TypeHelpers.GetEdmType <RefType>(targetEntityRef.ResultType).ElementType;

            if (!elementType1.EdmEquals((MetadataItem)elementType2) && !TypeSemantics.IsSubTypeOf((EdmType)elementType2, (EdmType)elementType1))
            {
                throw new ArgumentException(Strings.Cqt_RelatedEntityRef_TargetEntityNotCompatible, nameof(targetEntityRef));
            }
            this._targetEntityRef = targetEntityRef;
            this._targetEnd       = targetEnd;
            this._sourceEnd       = sourceEnd;
        }
        internal DbRelatedEntityRef(RelationshipEndMember sourceEnd, RelationshipEndMember targetEnd, DbExpression targetEntityRef)
        {
            // Validate that the specified relationship ends are:
            // 1. Non-null
            // 2. From the same metadata workspace as that used by the command tree
            EntityUtil.CheckArgumentNull(sourceEnd, "sourceEnd");
            EntityUtil.CheckArgumentNull(targetEnd, "targetEnd");

            // Validate that the specified target entity ref is:
            // 1. Non-null
            EntityUtil.CheckArgumentNull(targetEntityRef, "targetEntityRef");

            // Validate that the specified source and target ends are:
            // 1. Declared by the same relationship type
            if (!object.ReferenceEquals(sourceEnd.DeclaringType, targetEnd.DeclaringType))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndFromDifferentRelationship, "targetEnd");
            }
            // 2. Not the same end
            if (object.ReferenceEquals(sourceEnd, targetEnd))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndSameAsSourceEnd, "targetEnd");
            }

            // Validate that the specified target end has multiplicity of at most one
            if (targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.One &&
                targetEnd.RelationshipMultiplicity != RelationshipMultiplicity.ZeroOrOne)
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEndMustBeAtMostOne, "targetEnd");
            }

            // Validate that the specified target entity ref actually has a ref result type
            if (!TypeSemantics.IsReferenceType(targetEntityRef.ResultType))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEntityNotRef, "targetEntityRef");
            }

            // Validate that the specified target entity is of a type that can be reached by navigating to the specified relationship end
            EntityTypeBase endType    = TypeHelpers.GetEdmType <RefType>(targetEnd.TypeUsage).ElementType;
            EntityTypeBase targetType = TypeHelpers.GetEdmType <RefType>(targetEntityRef.ResultType).ElementType;

            //
            if (!endType.EdmEquals(targetType) && !TypeSemantics.IsSubTypeOf(targetType, endType))
            {
                throw EntityUtil.Argument(System.Data.Entity.Strings.Cqt_RelatedEntityRef_TargetEntityNotCompatible, "targetEntityRef");
            }

            // Validation succeeded, initialize state
            _targetEntityRef = targetEntityRef;
            _targetEnd       = targetEnd;
            _sourceEnd       = sourceEnd;
        }