internal static bool TryGetIsUnicode(TypeUsage type, out bool isUnicode) { if (!TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String)) { isUnicode = false; return(false); } return(TypeHelpers.TryGetBooleanFacetValue(type, DbProviderManifest.UnicodeFacetName, out isUnicode)); }
internal DbFilterExpression(TypeUsage resultType, DbExpressionBinding input, DbExpression predicate) : base(DbExpressionKind.Filter, resultType) { Debug.Assert(input != null, "DbFilterExpression input cannot be null"); Debug.Assert(predicate != null, "DbBFilterExpression predicate cannot be null"); Debug.Assert(TypeSemantics.IsPrimitiveType(predicate.ResultType, PrimitiveTypeKind.Boolean), "DbFilterExpression predicate must have a Boolean result type"); _input = input; _predicate = predicate; }
internal static bool SupportsCastToString(TypeUsage typeUsage) { return(TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.String) || TypeSemantics.IsNumericType(typeUsage) || TypeSemantics.IsBooleanType(typeUsage) || TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.DateTime) || TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.DateTimeOffset) || TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.Time) || TypeSemantics.IsPrimitiveType(typeUsage, PrimitiveTypeKind.Guid)); }
internal static bool TryGetScale(TypeUsage type, out byte scale) { if (!TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Decimal)) { scale = 0; return(false); } return(TryGetByteFacetValue(type, DbProviderManifest.ScaleFacetName, out scale)); }
internal static bool TryGetPrecision(TypeUsage type, out byte precision) { if (!TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Decimal)) { precision = 0; return(false); } return(TypeHelpers.TryGetByteFacetValue(type, DbProviderManifest.PrecisionFacetName, out precision)); }
internal DbQuantifierExpression(DbExpressionKind kind, TypeUsage booleanResultType, DbExpressionBinding input, DbExpression predicate) : base(kind, booleanResultType) { Debug.Assert(input != null, "DbQuantifierExpression input cannot be null"); Debug.Assert(predicate != null, "DbQuantifierExpression predicate cannot be null"); Debug.Assert(TypeSemantics.IsPrimitiveType(booleanResultType, PrimitiveTypeKind.Boolean), "DbQuantifierExpression must have a Boolean result type"); Debug.Assert(TypeSemantics.IsPrimitiveType(predicate.ResultType, PrimitiveTypeKind.Boolean), "DbQuantifierExpression predicate must have a Boolean result type"); this._input = input; this._predicate = predicate; }
internal DbFilterExpression(TypeUsage resultType, DbExpressionBinding input, DbExpression predicate) : base(DbExpressionKind.Filter, resultType) { DebugCheck.NotNull(input); DebugCheck.NotNull(predicate); Debug.Assert( TypeSemantics.IsPrimitiveType(predicate.ResultType, PrimitiveTypeKind.Boolean), "DbFilterExpression predicate must have a Boolean result type"); _input = input; _predicate = predicate; }
internal static bool TryGetMaxLength(TypeUsage type, out int maxLength) { if (!TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String) && !TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Binary)) { maxLength = 0; return(false); } // Binary and String FixedLength facets share the same name return(TypeHelpers.TryGetIntFacetValue(type, DbProviderManifest.MaxLengthFacetName, out maxLength)); }
private static void BuildTypeName(StringBuilder text, TypeUsage type) { var rowType = type.EdmType as RowType; var collType = type.EdmType as CollectionType; var refType = type.EdmType as RefType; if (TypeSemantics.IsPrimitiveType(type)) { text.Append(type); } else if (collType != null) { text.Append("Collection{"); BuildTypeName(text, collType.TypeUsage); text.Append("}"); } else if (refType != null) { text.Append("Ref<"); AppendFullName(text, refType.ElementType); text.Append(">"); } else if (rowType != null) { text.Append("Record["); var idx = 0; foreach (var recColumn in rowType.Properties) { text.Append("'"); text.Append(recColumn.Name); text.Append("'"); text.Append("="); BuildTypeName(text, recColumn.TypeUsage); idx++; if (idx < rowType.Properties.Count) { text.Append(", "); } } text.Append("]"); } else { // Entity, Relationship, Complex if (!string.IsNullOrEmpty(type.EdmType.NamespaceName)) { text.Append(type.EdmType.NamespaceName); text.Append("."); } text.Append(type.EdmType.Name); } }
internal static bool TryGetIsFixedLength(TypeUsage type, out bool isFixedLength) { if (!TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String) && !TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Binary)) { isFixedLength = false; return(false); } // Binary and String MaxLength facets share the same name return(TryGetBooleanFacetValue(type, DbProviderManifest.FixedLengthFacetName, out isFixedLength)); }
private static void BuildTypeName(StringBuilder text, TypeUsage type) { RowType edmType1 = type.EdmType as RowType; CollectionType edmType2 = type.EdmType as CollectionType; RefType edmType3 = type.EdmType as RefType; if (TypeSemantics.IsPrimitiveType(type)) { text.Append((object)type); } else if (edmType2 != null) { text.Append("Collection{"); ExpressionPrinter.PrinterVisitor.BuildTypeName(text, edmType2.TypeUsage); text.Append("}"); } else if (edmType3 != null) { text.Append("Ref<"); ExpressionPrinter.PrinterVisitor.AppendFullName(text, (EdmType)edmType3.ElementType); text.Append(">"); } else if (edmType1 != null) { text.Append("Record["); int num = 0; foreach (EdmProperty property in edmType1.Properties) { text.Append("'"); text.Append(property.Name); text.Append("'"); text.Append("="); ExpressionPrinter.PrinterVisitor.BuildTypeName(text, property.TypeUsage); ++num; if (num < edmType1.Properties.Count) { text.Append(", "); } } text.Append("]"); } else { if (!string.IsNullOrEmpty(type.EdmType.NamespaceName)) { text.Append(type.EdmType.NamespaceName); text.Append("."); } text.Append(type.EdmType.Name); } }
private static string GetTypeUsageToken(TypeUsage type) { string result = null; // Dev10#537010: EntityCommand false positive cache hits caused by insufficient parameter type information in cache key // Ensure String types are correctly differentiated. if (ReferenceEquals(type, DbTypeMap.AnsiString)) { result = "AnsiString"; } else if (ReferenceEquals(type, DbTypeMap.AnsiStringFixedLength)) { result = "AnsiStringFixedLength"; } else if (ReferenceEquals(type, DbTypeMap.String)) { result = "String"; } else if (ReferenceEquals(type, DbTypeMap.StringFixedLength)) { result = "StringFixedLength"; } else if (ReferenceEquals(type, DbTypeMap.Xml)) { // Xml is currently mapped to (unicode, variable-length) string, so the TypeUsage // given to the provider is actually a String TypeUsage. Debug.Assert( TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String), "Update GetTypeUsageToken to return 'Xml' for Xml parameters"); result = "String"; } else if (TypeSemantics.IsEnumerationType(type)) { result = type.EdmType.FullName; } else { // String/Xml TypeUsages are the only DbType-derived TypeUsages that carry meaningful facets. // Otherwise, the primitive type name is a sufficient token (note that full name is not required // since model types always have the 'Edm' namespace). Debug.Assert(TypeSemantics.IsPrimitiveType(type), "EntityParameter TypeUsage not a primitive type?"); Debug.Assert( !TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String), "String TypeUsage not derived from DbType.AnsiString, AnsiString, String, StringFixedLength or Xml?"); result = type.EdmType.Name; } return(result); }
internal DbLikeExpression(TypeUsage booleanResultType, DbExpression input, DbExpression pattern, DbExpression escape) : base(DbExpressionKind.Like, booleanResultType) { Debug.Assert(input != null, "DbLikeExpression argument cannot be null"); Debug.Assert(pattern != null, "DbLikeExpression pattern cannot be null"); Debug.Assert(escape != null, "DbLikeExpression escape cannot be null"); Debug.Assert(TypeSemantics.IsPrimitiveType(input.ResultType, PrimitiveTypeKind.String), "DbLikeExpression argument must have a string result type"); Debug.Assert(TypeSemantics.IsPrimitiveType(pattern.ResultType, PrimitiveTypeKind.String), "DbLikeExpression pattern must have a string result type"); Debug.Assert(TypeSemantics.IsPrimitiveType(escape.ResultType, PrimitiveTypeKind.String), "DbLikeExpression escape must have a string result type"); Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbLikeExpression must have a Boolean result type"); this._argument = input; this._pattern = pattern; this._escape = escape; }
internal DbLikeExpression(TypeUsage booleanResultType, DbExpression input, DbExpression pattern, DbExpression escape) : base(DbExpressionKind.Like, booleanResultType) { DebugCheck.NotNull(input); DebugCheck.NotNull(pattern); DebugCheck.NotNull(escape); Debug.Assert( TypeSemantics.IsPrimitiveType(input.ResultType, PrimitiveTypeKind.String), "DbLikeExpression argument must have a string result type"); Debug.Assert( TypeSemantics.IsPrimitiveType(pattern.ResultType, PrimitiveTypeKind.String), "DbLikeExpression pattern must have a string result type"); Debug.Assert( TypeSemantics.IsPrimitiveType(escape.ResultType, PrimitiveTypeKind.String), "DbLikeExpression escape must have a string result type"); Debug.Assert(TypeSemantics.IsBooleanType(booleanResultType), "DbLikeExpression must have a Boolean result type"); _argument = input; _pattern = pattern; _escape = escape; }
/// <summary> /// Adds the flattened properties on the input to the flattenedProperties list. /// </summary> /// <param name="input"></param> /// <param name="flattenedProperties"></param> private void FlattenProperties(DbExpression input, IList <DbPropertyExpression> flattenedProperties) { IList <EdmProperty> properties = TypeHelpers.GetProperties(input.ResultType); Debug.Assert(properties.Count != 0, "No nested properties when FlattenProperties called?"); for (int i = 0; i < properties.Count; i++) { DbExpression propertyInput = input; DbPropertyExpression propertyExpression = propertyInput.Property(properties[i]); if (TypeSemantics.IsPrimitiveType(properties[i].TypeUsage)) { flattenedProperties.Add(propertyExpression); } else { Debug.Assert(TypeSemantics.IsEntityType(properties[i].TypeUsage) || TypeSemantics.IsRowType(properties[i].TypeUsage), "The input to FlattenProperties is not of EntityType or RowType?"); FlattenProperties(propertyExpression, flattenedProperties); } } }
internal DbNotExpression(TypeUsage booleanResultType, DbExpression argument) : base(DbExpressionKind.Not, booleanResultType, argument) { Debug.Assert(TypeSemantics.IsPrimitiveType(booleanResultType, PrimitiveTypeKind.Boolean), "DbNotExpression requires a Boolean result type"); }
protected override void SetDbParameterValue(DbParameter parameter, TypeUsage parameterType, object value) { // Ensure a value that can be used with SqlParameter value = EnsureSqlParameterValue(value); if (TypeSemantics.IsPrimitiveType(parameterType, PrimitiveTypeKind.String) || TypeSemantics.IsPrimitiveType(parameterType, PrimitiveTypeKind.Binary)) { int?size = GetParameterSize(parameterType, ((parameter.Direction & ParameterDirection.Output) == ParameterDirection.Output)); if (!size.HasValue) { // Remember the current Size int previousSize = parameter.Size; // Infer the Size from the value parameter.Size = 0; parameter.Value = value; if (previousSize > -1) { // The 'max' length was chosen as a specific value for the parameter's Size property on Sql8 (4000 or 8000) // because no MaxLength was specified in the TypeUsage and the provider is Sql8. // If the value's length is less than or equal to this preset size, then the Size value can be retained, // otherwise this preset size must be removed in favor of the Size inferred from the value itself. // If the inferred Size is less than the preset 'max' size, restore that preset size if (parameter.Size < previousSize) { parameter.Size = previousSize; } } else { // -1 was chosen as the parameter's size because no MaxLength was specified in the TypeUsage and the // provider is more recent than Sql8. However, it is more optimal to specify a non-max (-1) value for // the size where possible, since 'max' parameters may prevent, for example, filter pushdown. // (see Dev10#617447 for more details) int suggestedLength = GetNonMaxLength(((SqlParameter)parameter).SqlDbType); if (parameter.Size < suggestedLength) { parameter.Size = suggestedLength; } else if (parameter.Size > suggestedLength) { // The parameter size is greater than the suggested length, so the suggested length cannot be used. // Since the provider is Sql9 or newer, set the size to max (-1) instead of the inferred size for better plan reuse. parameter.Size = -1; } } } else { // Just set the value parameter.Value = value; } } else { // Not a string or binary parameter - just set the value parameter.Value = value; } }
// <summary> // Constructs a SqlCeParameter // </summary> internal static DbParameter CreateSqlCeParameter( string name, TypeUsage type, object value, bool ignoreMaxLengthFacet, bool isLocalProvider) { var rdpSqlCeParameter = Type.GetType(RemoteProvider.SqlCeParameter); // No other parameter type is supported. // DebugCheck.NotNull(type); int? size; byte?precision; byte?scale; var result = isLocalProvider ? new SqlCeParameter() : (DbParameter)RemoteProviderHelper.CreateRemoteProviderType(RemoteProvider.SqlCeParameter); result.ParameterName = name; result.Value = value; // .Direction // parameter.Direction - take the default. we don't support output parameters. result.Direction = ParameterDirection.Input; // .Size, .Precision, .Scale and .SqlDbType var sqlDbType = GetSqlDbType(type, out size, out precision, out scale); // Skip guessing the parameter type (only for strings & blobs) if parameter size is not available // Instead, let QP take proper guess at execution time with available details. // if ((null != size) || (!TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.String) && !TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Binary))) { if (isLocalProvider) { var sqlCeParameter = (SqlCeParameter)result; if (sqlCeParameter.SqlDbType != sqlDbType) { sqlCeParameter.SqlDbType = sqlDbType; } } else { // Remote Provider is loaded by reflection. As SqlDbType is not part of the base interface // We need to access this using reflection only. var rdpType = RemoteProviderHelper.GetRemoteProviderType(RemoteProvider.SqlCeParameter); var rdpInfo = rdpType.GetProperty("SqlDbType"); rdpInfo.SetValue(result, sqlDbType, null); } } // Note that we overwrite 'facet' parameters where either the value is different or // there is an output parameter. This is because output parameters in SqlClient have their // facets clobbered if they are implicitly set (e.g. if the Precision was implicitly set // by setting the value) if (!ignoreMaxLengthFacet && size.HasValue && (result.Size != size.Value)) { result.Size = size.Value; } if (precision.HasValue && (((IDbDataParameter)result).Precision != precision.Value)) { ((IDbDataParameter)result).Precision = precision.Value; } if (scale.HasValue && (((IDbDataParameter)result).Scale != scale.Value)) { ((IDbDataParameter)result).Scale = scale.Value; } // .IsNullable var isNullable = TypeSemantics.IsNullable(type); if (isNullable != result.IsNullable) { result.IsNullable = isNullable; } return(result); }
protected static void AssertBoolean(TypeUsage type) { Assert( TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Boolean), "Type Mismatch: Expected Boolean; found {0} instead", type.ToString()); }
private void WriteFunctionElement(EdmFunction function) { _writer.WriteStartElement(function.IsFunctionImport ? XmlConstants.FunctionImport : XmlConstants.Function); _writer.WriteAttributeString(XmlConstants.Name, function.Name); // Write function ReturnType as attribute if possible. bool returnParameterHandled = false; if (function.ReturnParameter != null) { var returnTypeUsage = function.ReturnParameter.TypeUsage; bool collection = returnTypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType; if (collection) { Debug.Assert(_schemaVersion >= EntityFrameworkVersions.Version3, "_schemaVersion >= EntityFrameworkVersions.Version3"); returnTypeUsage = ((CollectionType)returnTypeUsage.EdmType).TypeUsage; } if (TypeSemantics.IsPrimitiveType(returnTypeUsage) || TypeSemantics.IsNominalType(returnTypeUsage)) { string typeName = GetFullName(returnTypeUsage.EdmType); if (collection) { typeName = "Collection(" + typeName + ")"; } _writer.WriteAttributeString(XmlConstants.ReturnType, typeName); returnParameterHandled = true; } } if (!_isModel) { _writer.WriteAttributeString(XmlConstants.AggregateAttribute, GetAttributeValueString(function.AggregateAttribute)); _writer.WriteAttributeString(XmlConstants.BuiltInAttribute, GetAttributeValueString(function.BuiltInAttribute)); _writer.WriteAttributeString(XmlConstants.NiladicFunction, GetAttributeValueString(function.NiladicFunctionAttribute)); _writer.WriteAttributeString(XmlConstants.IsComposable, GetAttributeValueString(function.IsComposableAttribute)); _writer.WriteAttributeString(XmlConstants.ParameterTypeSemantics, GetAttributeValueString(function.ParameterTypeSemanticsAttribute)); } else if (function.IsFunctionImport && function.IsComposableAttribute) { Debug.Assert(_schemaVersion >= EntityFrameworkVersions.Version3, "_schemaVersion >= EntityFrameworkVersions.Version3"); _writer.WriteAttributeString(XmlConstants.IsComposable, GetAttributeValueString(true)); } if (function.StoreFunctionNameAttribute != null) { _writer.WriteAttributeString(XmlConstants.StoreFunctionName, function.StoreFunctionNameAttribute); } if (function.CommandTextAttribute != null) { Debug.Assert(!_isModel, "Serialization of CommandTextAttribute is not supported for CSDL."); _writer.WriteAttributeString(XmlConstants.CommandText, function.CommandTextAttribute); } if (function.Schema != null) { _writer.WriteAttributeString(XmlConstants.Schema, function.Schema); } foreach (FunctionParameter parameter in function.Parameters) { WriteFunctionParameterElement(parameter); } // Write function ReturnType subelement if needed. if (function.ReturnParameter != null && !returnParameterHandled) { // Handle a TVF in s-space: Collection(RowType) if (function.ReturnParameter.TypeUsage.EdmType.BuiltInTypeKind == BuiltInTypeKind.CollectionType) { Debug.Assert(_schemaVersion >= EntityFrameworkVersions.Version3 && !_isModel, "_schemaVersion >= EntityFrameworkVersions.Version3 && !_isModel"); var elementType = ((CollectionType)function.ReturnParameter.TypeUsage.EdmType).TypeUsage.EdmType; Debug.Assert(elementType.BuiltInTypeKind == BuiltInTypeKind.RowType, "TVF return type is expected to be Collection(RowType)"); var rowType = (RowType)elementType; _writer.WriteStartElement(XmlConstants.ReturnType); _writer.WriteStartElement(XmlConstants.CollectionType); WriteTypeElement(rowType); _writer.WriteEndElement(); _writer.WriteEndElement(); returnParameterHandled = true; } } Debug.Assert(function.ReturnParameter == null || returnParameterHandled, "ReturnParameter was not handled."); _writer.WriteEndElement(); }
protected static void AssertBoolean(TypeUsage type) { Assert(TypeSemantics.IsPrimitiveType(type, PrimitiveTypeKind.Boolean), "Type Mismatch: Expected Boolean; found {0} instead", TypeHelpers.GetFullName(type)); }
internal DbOrExpression(TypeUsage booleanResultType, DbExpression left, DbExpression right) : base(DbExpressionKind.Or, booleanResultType, left, right) { Debug.Assert( TypeSemantics.IsPrimitiveType(booleanResultType, PrimitiveTypeKind.Boolean), "DbOrExpression requires a Boolean result type"); }
internal static DbExpression ConvertToString(ExpressionConverter parent, LinqExpression linqExpression) { if (linqExpression.Type == typeof(object)) { var constantExpression = linqExpression as ConstantExpression; linqExpression = constantExpression != null? Expression.Constant(constantExpression.Value) : linqExpression.RemoveConvert(); } var expression = parent.TranslateExpression(linqExpression); var clrType = TypeSystem.GetNonNullableType(linqExpression.Type); if (clrType.IsEnum) { //Flag enums are not supported. if (Attribute.IsDefined(clrType, typeof(FlagsAttribute))) { throw new NotSupportedException(Strings.Elinq_ToStringNotSupportedForEnumsWithFlags); } if (linqExpression.IsNullConstant()) { return(DbExpressionBuilder.Constant(string.Empty)); } //Constant expression, optimize to constant name if (linqExpression.NodeType == ExpressionType.Constant) { var value = ((ConstantExpression)linqExpression).Value; var name = Enum.GetName(clrType, value) ?? value.ToString(); return(DbExpressionBuilder.Constant(name)); } var integralType = clrType.GetEnumUnderlyingType(); var type = parent.GetValueLayerType(integralType); var values = clrType.GetEnumValues() .Cast <object>() .Select(v => System.Convert.ChangeType(v, integralType, CultureInfo.InvariantCulture)) //cast to integral type so that unmapped enum types works too .Select(v => DbExpressionBuilder.Constant(v)) .Select(c => (DbExpression)expression.CastTo(type).Equal(c)) //cast expression to integral type before comparing to constant .Concat(new[] { expression.CastTo(type).IsNull() }); // default case var names = clrType.GetEnumNames() .Select(s => DbExpressionBuilder.Constant(s)) .Concat(new[] { DbExpressionBuilder.Constant(string.Empty) }); // default case //translate unnamed enum values for the else clause, raw linq -> as integral value -> translate to cqt -> to string //e.g. ((DayOfWeek)99) -> "99" var asIntegralLinq = LinqExpression.Convert(linqExpression, integralType); var asStringCqt = parent .TranslateExpression(asIntegralLinq) .CastTo(parent.GetValueLayerType(typeof(string))); return(DbExpressionBuilder.Case(values, names, asStringCqt)); } else if (TypeSemantics.IsPrimitiveType(expression.ResultType, PrimitiveTypeKind.String)) { return(StripNull(linqExpression, expression, expression)); } else if (TypeSemantics.IsPrimitiveType(expression.ResultType, PrimitiveTypeKind.Guid)) { return(StripNull(linqExpression, expression, expression.CastTo(parent.GetValueLayerType(typeof(string))).ToLower())); } else if (TypeSemantics.IsPrimitiveType(expression.ResultType, PrimitiveTypeKind.Boolean)) { if (linqExpression.IsNullConstant()) { return(DbExpressionBuilder.Constant(string.Empty)); } if (linqExpression.NodeType == ExpressionType.Constant) { var name = ((ConstantExpression)linqExpression).Value.ToString(); return(DbExpressionBuilder.Constant(name)); } var whenTrue = expression.Equal(DbExpressionBuilder.True); var whenFalse = expression.Equal(DbExpressionBuilder.False); var thenTrue = DbExpressionBuilder.Constant(true.ToString()); var thenFalse = DbExpressionBuilder.Constant(false.ToString()); return(DbExpressionBuilder.Case( new[] { whenTrue, whenFalse }, new[] { thenTrue, thenFalse }, DbExpressionBuilder.Constant(string.Empty))); } else { if (!SupportsCastToString(expression.ResultType)) { throw new NotSupportedException( Strings.Elinq_ToStringNotSupportedForType(expression.ResultType.EdmType.Name)); } //treat all other types as a simple cast return(StripNull(linqExpression, expression, expression.CastTo(parent.GetValueLayerType(typeof(string))))); } }