internal SqlUnary UnaryValueOf(SqlExpression expression, Expression sourceExpression) { Type valueType = TypeSystem.GetNonNullableType(expression.ClrType); return(new SqlUnary(SqlNodeType.ValueOf, valueType, expression.SqlType, expression, null, sourceExpression)); }
internal override SqlNode Visit(SqlNode node) { if (node == null) { return(null); } sourceExpression = node as SqlExpression; if (sourceExpression != null) { Type type = sourceExpression.ClrType; UnwrapStack unwrap = this.UnwrapSequences; while (unwrap != null) { if (unwrap.Unwrap) { type = TypeSystem.GetElementType(type); } unwrap = unwrap.Last; } sourceType = type; } if (sourceType != null && TypeSystem.GetNonNullableType(sourceType).IsValueType) { return(node); // Value types can't also have a dynamic type. } if (sourceType != null && TypeSystem.HasIEnumerable(sourceType)) { return(node); // Sequences can't be polymorphic. } switch (node.NodeType) { case SqlNodeType.ScalarSubSelect: case SqlNodeType.Multiset: case SqlNodeType.Element: case SqlNodeType.SearchedCase: case SqlNodeType.ClientCase: case SqlNodeType.SimpleCase: case SqlNodeType.Member: case SqlNodeType.DiscriminatedType: case SqlNodeType.New: case SqlNodeType.FunctionCall: case SqlNodeType.MethodCall: case SqlNodeType.Convert: // Object identity does not survive convert. It does survive Cast. // Dig no further. return(node); case SqlNodeType.TypeCase: sourceType = ((SqlTypeCase)node).RowType.Type; return(node); case SqlNodeType.Link: sourceType = ((SqlLink)node).RowType.Type; return(node); case SqlNodeType.Table: sourceType = ((SqlTable)node).RowType.Type; return(node); case SqlNodeType.Value: SqlValue val = (SqlValue)node; if (val.Value != null) { // In some cases the ClrType of a Value node may // differ from the actual runtime type of the value. // Therefore, we ensure here that the correct type is set. sourceType = val.Value.GetType(); } return(node); } return(base.Visit(node)); }
internal override SqlExpression VisitUnaryOperator(SqlUnary uo) { uo.Operand = this.VisitExpression(uo.Operand); if (uo.NodeType != SqlNodeType.Convert) { return(uo); } ProviderType oldSqlType = uo.Operand.SqlType; ProviderType newSqlType = uo.SqlType; Type oldClrType = TypeSystem.GetNonNullableType(uo.Operand.ClrType); Type newClrType = TypeSystem.GetNonNullableType(uo.ClrType); if (newClrType == typeof(char)) { if (oldClrType == typeof(bool)) { throw Error.ConvertToCharFromBoolNotSupported(); } if (oldSqlType.IsNumeric) { // numeric --> char return(sql.FunctionCall(uo.ClrType, "NCHAR", new SqlExpression[] { uo.Operand }, uo.SourceExpression)); } if (StringConversionIsSafe(oldSqlType, newSqlType)) { if (StringConversionIsNeeded(oldSqlType, newSqlType)) { // set the new size to the (potentially smaller) oldSqlType.Size uo.SetSqlType(sql.TypeProvider.From(uo.ClrType, oldSqlType.HasSizeOrIsLarge ? oldSqlType.Size : (int?)null)); } } else { throw Error.UnsafeStringConversion(oldSqlType.ToQueryString(), newSqlType.ToQueryString()); } } else if (oldClrType == typeof(char) && (oldSqlType.IsChar || oldSqlType.IsString) && newSqlType.IsNumeric) { // char --> int return(sql.FunctionCall(newClrType, sql.TypeProvider.From(typeof(int)), "UNICODE", new SqlExpression[] { uo.Operand }, uo.SourceExpression)); } else if (newClrType == typeof(string)) { if (oldClrType == typeof(double)) { // use longer format if it was a double in the CLR expression return(ConvertDoubleToString(uo.Operand, uo.ClrType)); } else if (oldClrType == typeof(bool)) { // use 'true' or 'false' if it was a bool in the CLR expression return(ConvertBitToString(uo.Operand, uo.ClrType)); } else if (StringConversionIsSafe(oldSqlType, newSqlType)) { if (StringConversionIsNeeded(oldSqlType, newSqlType)) { // set the new size to the (potentially smaller) oldSqlType.Size uo.SetSqlType(sql.TypeProvider.From(uo.ClrType, oldSqlType.HasSizeOrIsLarge ? oldSqlType.Size : (int?)null)); } } else { throw Error.UnsafeStringConversion(oldSqlType.ToQueryString(), newSqlType.ToQueryString()); } } return(uo); }
internal override Expression VisitMemberAccess(MemberExpression m) { if (MetaPosition.AreSameMember(m.Member, association.ThisMember.Member)) { var keyValues = GetKeyValues(Visit(m.Expression), association.ThisKey); return(WhereClauseFromSourceAndKeys(otherSouce, association.OtherKey.ToArray(), keyValues)); } var expression = Visit(m.Expression); if (expression != m.Expression) { if (expression.Type != m.Expression.Type && m.Member.Name == "Count" && TypeSystem.IsSequenceType(expression.Type)) { return(Expression.Call(typeof(Enumerable), "Count", new Type[1] { TypeSystem.GetElementType(expression.Type) }, expression)); } return(Expression.MakeMemberAccess(expression, m.Member)); } return(m); }
private static bool IsNullableHasValue(SqlMember m) { return(TypeSystem.IsNullableType(m.Expression.ClrType) && m.Member.Name == "HasValue"); }