private bool TryGetValueLayerType(Type linqType, out TypeUsage type)
{
// Remove nullable
var nonNullableType = TypeSystem.GetNonNullableType(linqType);
// Enum types are only supported for EDM V3 and higher, do not force loading
// enum types for previous versions of EDM
if (nonNullableType.IsEnum() && this.EdmItemCollection.EdmVersion < XmlConstants.EdmVersionForV3)
{
nonNullableType = nonNullableType.GetEnumUnderlyingType();
}
// See if this is a primitive type
PrimitiveTypeKind primitiveTypeKind;
if (ClrProviderManifest.TryGetPrimitiveTypeKind(nonNullableType, out primitiveTypeKind))
{
type = EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(primitiveTypeKind);
return true;
}
// See if this is a collection type (if so, recursively resolve)
var elementType = TypeSystem.GetElementType(nonNullableType);
if (elementType != nonNullableType)
{
TypeUsage elementTypeUsage;
if (TryGetValueLayerType(elementType, out elementTypeUsage))
{
type = TypeHelpers.CreateCollectionTypeUsage(elementTypeUsage);
return true;
}
}
// Ensure the metadata for this object type is loaded
_perspective.MetadataWorkspace.ImplicitLoadAssemblyForType(linqType, null);
if (!_perspective.TryGetTypeByName(nonNullableType.FullNameWithNesting(), false, out type))
{
// If the user is casting to a type that is not a model type or a primitive type it can be a cast to an enum that
// is not in the model. In that case we use the underlying enum type.
// Note that if the underlying type is not any of the EF primitive types we will fail with and InvalidCastException.
// This is consistent with what we would do when seeing a cast to a primitive type that is not a EF valid primitive
// type (e.g. ulong).
if (nonNullableType.IsEnum()
&& ClrProviderManifest.TryGetPrimitiveTypeKind(nonNullableType.GetEnumUnderlyingType(), out primitiveTypeKind))
{
type = EdmProviderManifest.Instance.GetCanonicalModelTypeUsage(primitiveTypeKind);
}
}
return type != null;
}