private TypeUsage GetCastTargetType(TypeUsage fromType, Type toClrType, Type fromClrType, bool preserveCastForDateTime)
{
// An IQueryable can report its type as ObjectQuery, IQueryable, or IOrderedQueryable depending on how the type and
// expression tree were created. At this point in the translation, unwrapping of the DbQuery to ObjectQuery has already
// happened and checking for something other than ObjectQuery has already been done. Therefore, from a CQT translation
// perspective we can treat all these types as the same and this therefore becomes a no-op.
if (fromClrType != null
&& fromClrType.IsGenericType()
&& toClrType.IsGenericType()
&& (fromClrType.GetGenericTypeDefinition() == typeof(ObjectQuery<>)
|| fromClrType.GetGenericTypeDefinition() == typeof(IQueryable<>)
|| fromClrType.GetGenericTypeDefinition() == typeof(IOrderedQueryable<>))
&& (toClrType.GetGenericTypeDefinition() == typeof(ObjectQuery<>)
|| toClrType.GetGenericTypeDefinition() == typeof(IQueryable<>)
|| toClrType.GetGenericTypeDefinition() == typeof(IOrderedQueryable<>))
&& fromClrType.GetGenericArguments()[0] == toClrType.GetGenericArguments()[0])
{
return null;
}
//ignore System.Enum
if (fromClrType != null
&& TypeSystem.GetNonNullableType(fromClrType).IsEnum
&& toClrType == typeof(Enum))
{
return null;
}
// If the types are the same or the fromType is assignable to toType, return null
// (indicating no cast is required)
TypeUsage toType;
if (TryGetValueLayerType(toClrType, out toType)
&& CanOmitCast(fromType, toType, preserveCastForDateTime))
{
return null;
}
// Check that the cast is supported and adjust the target type as necessary.
toType = ValidateAndAdjustCastTypes(toType, fromType, toClrType, fromClrType);
return toType;
}