/// <summary>
        /// Get key value pair array for specific odata resource using specific entity type
        /// </summary>
        /// <param name="resource">The resource instance.</param>
        /// <param name="serializationInfo">The serialization info of the resource for writing without model.</param>
        /// <param name="actualEntityType">The edm entity type of the resource</param>
        /// <param name="requiresId">Whether key properties are required to be returned</param>
        /// <returns>Key value pair array</returns>
        internal static KeyValuePair <string, object>[] GetKeyProperties(
            ODataResourceBase resource,
            ODataResourceSerializationInfo serializationInfo,
            IEdmEntityType actualEntityType,
            bool requiresId)
        {
            Debug.Assert(resource != null, "GetKeyProperties called for a null resource.");

            KeyValuePair <string, object>[] keyProperties = null;
            string actualEntityTypeName = string.IsNullOrEmpty(resource.TypeName) ? actualEntityType?.FullName() : resource.TypeName;

            // if we have serializationInfo, try that first
            if (serializationInfo != null)
            {
                keyProperties = ODataResourceMetadataContextWithoutModel.GetPropertiesBySerializationInfoPropertyKind(resource, ODataPropertyKind.Key, actualEntityTypeName);
            }

            // if we didn't get any keys from serializationInfo, try using entity type
            if ((keyProperties == null || keyProperties.Length == 0) && actualEntityType != null)
            {
                keyProperties = GetPropertyValues(actualEntityType.Key(), resource, actualEntityType, requiresId).ToArray();
            }

            if (!ValidateEntityTypeHasKeyProperties(keyProperties, actualEntityTypeName, requiresId))
            {
                return(Enumerable.Empty <KeyValuePair <string, object> >().ToArray());
            }

            return(keyProperties);
        }
        /// <summary>
        /// Get key value pair array for specifc odata resource using specifc entity type
        /// </summary>
        /// <param name="resource">The resource instance.</param>
        /// <param name="serializationInfo">The serialization info of the resource for writing without model.</param>
        /// <param name="actualEntityType">The edm entity type of the resource</param>
        /// <returns>Key value pair array</returns>
        internal static KeyValuePair <string, object>[] GetKeyProperties(
            ODataResource resource,
            ODataResourceSerializationInfo serializationInfo,
            IEdmEntityType actualEntityType)
        {
            KeyValuePair <string, object>[] keyProperties = null;
            string actualEntityTypeName = null;

            if (serializationInfo != null)
            {
                if (String.IsNullOrEmpty(resource.TypeName))
                {
                    throw new ODataException(Strings.ODataResourceTypeContext_ODataResourceTypeNameMissing);
                }

                actualEntityTypeName = resource.TypeName;
                keyProperties        = ODataResourceMetadataContextWithoutModel.GetPropertiesBySerializationInfoPropertyKind(resource, ODataPropertyKind.Key, actualEntityTypeName);
            }
            else
            {
                actualEntityTypeName = actualEntityType.FullName();

                IEnumerable <IEdmStructuralProperty> edmKeyProperties = actualEntityType.Key();
                if (edmKeyProperties != null)
                {
                    keyProperties = edmKeyProperties.Select(p => new KeyValuePair <string, object>(p.Name, GetPrimitiveOrEnumPropertyValue(resource, p.Name, actualEntityTypeName, /*isKeyProperty*/ false))).ToArray();
                }
            }

            ValidateEntityTypeHasKeyProperties(keyProperties, actualEntityTypeName);
            return(keyProperties);
        }
        /// <summary>
        /// Get key value pair array for specific odata resource using specific entity type
        /// </summary>
        /// <param name="resource">The resource instance.</param>
        /// <param name="serializationInfo">The serialization info of the resource for writing without model.</param>
        /// <param name="actualEntityType">The edm entity type of the resource</param>
        /// <returns>Key value pair array</returns>
        internal static KeyValuePair <string, object>[] GetKeyProperties(
            ODataResourceBase resource,
            ODataResourceSerializationInfo serializationInfo,
            IEdmEntityType actualEntityType)
        {
            KeyValuePair <string, object>[] keyProperties = null;
            string actualEntityTypeName = null;

            if (serializationInfo != null)
            {
                if (String.IsNullOrEmpty(resource.TypeName))
                {
                    throw new ODataException(Strings.ODataResourceTypeContext_ODataResourceTypeNameMissing);
                }

                actualEntityTypeName = resource.TypeName;
                keyProperties        = ODataResourceMetadataContextWithoutModel.GetPropertiesBySerializationInfoPropertyKind(resource, ODataPropertyKind.Key, actualEntityTypeName);
            }
            else
            {
                keyProperties = GetPropertyValues(actualEntityType.Key(), resource, actualEntityType, /*isKeyProperty*/ true, /*isRequired*/ true).ToArray();
            }

            ValidateEntityTypeHasKeyProperties(keyProperties, actualEntityTypeName);
            return(keyProperties);
        }