private Sql.ExpressionAttribute GetDbFunctionFromMethodCall(Type type, MethodInfo methodInfo) { if (_dependencies == null || _model == null) { return(null); } methodInfo = (MethodInfo)type.GetMemberEx(methodInfo) ?? methodInfo; var found = _calculatedExtensions.GetOrAdd(methodInfo, mi => { EFCoreExpressionAttribute result = null; if (!methodInfo.IsGenericMethodDefinition && !mi.GetCustomAttributes <Sql.ExpressionAttribute>().Any()) { var value = Expression.Constant(DefaultValue.GetValue(type), type); var objExpr = new SqlTransparentExpression(value, _mappingSource?.FindMapping(type)); var parameterInfos = methodInfo.GetParameters(); var parametersArray = parameterInfos .Select(p => (SqlExpression) new SqlTransparentExpression( Expression.Constant(DefaultValue.GetValue(p.ParameterType), p.ParameterType), _mappingSource?.FindMapping(p.ParameterType))).ToArray(); var newExpression = _dependencies.MethodCallTranslatorProvider.Translate(_model, objExpr, methodInfo, parametersArray); if (newExpression != null) { if (!methodInfo.IsStatic) { parametersArray = new SqlExpression[] { objExpr } } .Concat(parametersArray).ToArray(); result = ConvertToExpressionAttribute(methodInfo, newExpression, parametersArray); }
private string GetVariableType(ColumnModification columnModification) { return(_typeMappingSource.FindMapping(columnModification.Property).StoreType); }
public SqlExpression Translate(SqlExpression instance, MethodInfo method, IReadOnlyList <SqlExpression> arguments, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { var traversal = GetTraversalExpression(instance, arguments); if (traversal == null) { return(null); } if (typeof(JToken).IsAssignableFrom(method.DeclaringType) && method.Name == "get_Item" && arguments.Count == 1) { var indexExpression = _sqlExpressionFactory.ApplyDefaultTypeMapping(arguments[0]); if (method.DeclaringType == typeof(JArray) || indexExpression.Type == typeof(int)) { // Try translating indexing inside json column. return(_jsonPocoTranslator.TranslateMemberAccess( traversal, _sqlExpressionFactory.JsonArrayIndex(indexExpression), method.ReturnType)); } return(traversal.Append( ApplyPathLocationTypeMapping(arguments[0]), method.DeclaringType, _typeMappingSource.FindMapping(method.DeclaringType))); } // Support for .Value<T>() and .Value<U, T>(): if (instance == null && method.Name == nameof(global::Newtonsoft.Json.Linq.Extensions.Value) && method.DeclaringType == typeof(global::Newtonsoft.Json.Linq.Extensions) && method.IsGenericMethod && method.GetParameters().Length == 1 && arguments.Count == 1) { return(ConvertFromJsonExtract( traversal.Clone( method.ReturnType == typeof(string), method.ReturnType, _typeMappingSource.FindMapping(method.ReturnType) ), method.ReturnType)); } // Support for Count() if (instance == null && method.Name == nameof(Enumerable.Count) && method.DeclaringType == typeof(Enumerable) && method.IsGenericMethod && method.GetParameters().Length == 1 && arguments.Count == 1) { return(_jsonPocoTranslator.TranslateArrayLength(traversal)); } // Predicate-less Any - translate to a simple length check. if (method.IsClosedFormOf(_enumerableAnyWithoutPredicate) && arguments.Count == 1 && arguments[0].Type.TryGetElementType(out _) && arguments[0].TypeMapping is MySqlJsonTypeMapping) { return(_sqlExpressionFactory.GreaterThan( _jsonPocoTranslator.TranslateArrayLength(arguments[0]), _sqlExpressionFactory.Constant(0))); } return(null); }
/// <summary> /// This API supports the Entity Framework Core infrastructure and is not intended to be used /// directly from your code. This API may change or be removed in future releases. /// </summary> public virtual TypeScaffoldingInfo FindMapping( string storeType, bool keyOrIndex, bool rowVersion) { // This is because certain providers can have no type specified as a default type e.g. SQLite Check.NotNull(storeType, nameof(storeType)); var mapping = _typeMappingSource.FindMapping(storeType); if (mapping == null) { return(null); } var canInfer = false; bool?scaffoldUnicode = null; int? scaffoldMaxLength = null; if (mapping.ClrType == typeof(byte[])) { // Check for inference var byteArrayMapping = _typeMappingSource.FindMapping( typeof(byte[]), keyOrIndex, rowVersion: rowVersion, size: mapping.Size); if (byteArrayMapping.StoreType.Equals(storeType, StringComparison.OrdinalIgnoreCase)) { canInfer = true; // Check for size var sizedMapping = _typeMappingSource.FindMapping( typeof(byte[]), keyOrIndex, rowVersion: rowVersion); scaffoldMaxLength = sizedMapping.Size != byteArrayMapping.Size ? byteArrayMapping.Size : null; } } else if (mapping.ClrType == typeof(string)) { // Check for inference var stringMapping = _typeMappingSource.FindMapping( typeof(string), keyOrIndex, unicode: mapping.IsUnicode, size: mapping.Size); if (stringMapping.StoreType.Equals(storeType, StringComparison.OrdinalIgnoreCase)) { canInfer = true; // Check for unicode var unicodeMapping = _typeMappingSource.FindMapping( typeof(string), keyOrIndex, unicode: true, size: mapping.Size); scaffoldUnicode = unicodeMapping.IsUnicode != stringMapping.IsUnicode ? (bool?)stringMapping.IsUnicode : null; // Check for size var sizedMapping = _typeMappingSource.FindMapping( typeof(string), keyOrIndex, unicode: mapping.IsUnicode); scaffoldMaxLength = sizedMapping.Size != stringMapping.Size ? stringMapping.Size : null; } } else { var defaultMapping = _typeMappingSource.GetMapping(mapping.ClrType); if (defaultMapping.StoreType.Equals(storeType, StringComparison.OrdinalIgnoreCase)) { canInfer = true; } } return(new TypeScaffoldingInfo( mapping.ClrType, canInfer, scaffoldUnicode, scaffoldMaxLength)); }
public static RelationalTypeMapping GetMapping( IRelationalTypeMappingSource typeMappingSource, IProperty property) => typeMappingSource.FindMapping(property);
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression?Translate( SqlExpression?instance, MemberInfo member, Type returnType, IDiagnosticsLogger <DbLoggerCategory.Query> logger) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); Check.NotNull(logger, nameof(logger)); if (typeof(Polygon).IsAssignableFrom(member.DeclaringType)) { Check.DebugAssert(instance !.TypeMapping != null, "Instance must have typeMapping assigned."); var storeType = instance.TypeMapping.StoreType; var isGeography = string.Equals(storeType, "geography", StringComparison.OrdinalIgnoreCase); if (isGeography) { if (Equals(_exteriorRing, member)) { return(_sqlExpressionFactory.Function( instance, "RingN", new[] { _sqlExpressionFactory.Constant(1) }, nullable: true, instancePropagatesNullability: true, argumentsPropagateNullability: new[] { false }, returnType, _typeMappingSource.FindMapping(returnType, storeType))); } if (Equals(_numInteriorRings, member)) { return(_sqlExpressionFactory.Subtract( _sqlExpressionFactory.Function( instance, "NumRings", Array.Empty <SqlExpression>(), nullable: true, instancePropagatesNullability: true, argumentsPropagateNullability: Array.Empty <bool>(), returnType), _sqlExpressionFactory.Constant(1))); } } if (_geometryMemberToFunctionName.TryGetValue(member, out var functionName)) { var resultTypeMapping = typeof(Geometry).IsAssignableFrom(returnType) ? _typeMappingSource.FindMapping(returnType, storeType) : _typeMappingSource.FindMapping(returnType); return(_sqlExpressionFactory.Function( instance, functionName, Array.Empty <SqlExpression>(), nullable: true, instancePropagatesNullability: true, argumentsPropagateNullability: Array.Empty <bool>(), returnType, resultTypeMapping)); } } return(null); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual TypeScaffoldingInfo?FindMapping( string storeType, bool keyOrIndex, bool rowVersion) { // This is because certain providers can have no type specified as a default type e.g. SQLite Check.NotNull(storeType, nameof(storeType)); var mapping = _typeMappingSource.FindMapping(storeType); if (mapping == null) { return(null); } var canInfer = false; bool?scaffoldUnicode = null; bool?scaffoldFixedLength = null; int? scaffoldMaxLength = null; int? scaffoldPrecision = null; int? scaffoldScale = null; var unwrappedClrType = mapping.ClrType.UnwrapNullableType(); // Check for inference var defaultTypeMapping = _typeMappingSource.FindMapping( unwrappedClrType, null, keyOrIndex, unicode: mapping.IsUnicode, size: mapping.Size, rowVersion: rowVersion, fixedLength: mapping.IsFixedLength, precision: mapping.Precision, scale: mapping.Scale); if (defaultTypeMapping != null && string.Equals(defaultTypeMapping.StoreType, storeType, StringComparison.Ordinal)) { canInfer = true; // Check for Unicode var unicodeMapping = _typeMappingSource.FindMapping( unwrappedClrType, null, keyOrIndex, unicode: null, size: mapping.Size, rowVersion: rowVersion, fixedLength: mapping.IsFixedLength, precision: mapping.Precision, scale: mapping.Scale) !; scaffoldUnicode = unicodeMapping.IsUnicode != defaultTypeMapping.IsUnicode ? (bool?)defaultTypeMapping.IsUnicode : null; // Check for fixed-length var fixedLengthMapping = _typeMappingSource.FindMapping( unwrappedClrType, null, keyOrIndex, unicode: mapping.IsUnicode, size: mapping.Size, fixedLength: null, precision: mapping.Precision, scale: mapping.Scale) !; scaffoldFixedLength = fixedLengthMapping.IsFixedLength != defaultTypeMapping.IsFixedLength ? (bool?)defaultTypeMapping.IsFixedLength : null; // Check for size (= max-length) var sizedMapping = _typeMappingSource.FindMapping( unwrappedClrType, null, keyOrIndex, unicode: mapping.IsUnicode, size: null, rowVersion: rowVersion, fixedLength: false, // Fixed length with no size is not valid precision: mapping.Precision, scale: mapping.Scale) !; scaffoldMaxLength = sizedMapping.Size != defaultTypeMapping.Size ? defaultTypeMapping.Size : null; // Check for precision var precisionMapping = _typeMappingSource.FindMapping( unwrappedClrType, null, keyOrIndex, unicode: mapping.IsUnicode, size: mapping.Size, rowVersion: rowVersion, fixedLength: mapping.IsFixedLength, precision: null, scale: mapping.Scale) !; scaffoldPrecision = precisionMapping.Precision != defaultTypeMapping.Precision ? defaultTypeMapping.Precision : null; // Check for scale var scaleMapping = _typeMappingSource.FindMapping( unwrappedClrType, null, keyOrIndex, unicode: mapping.IsUnicode, size: mapping.Size, rowVersion: rowVersion, fixedLength: mapping.IsFixedLength, precision: mapping.Precision, scale: null) !; scaffoldScale = scaleMapping.Scale != defaultTypeMapping.Scale ? defaultTypeMapping.Scale : null; } return(new TypeScaffoldingInfo( mapping.ClrType, canInfer, scaffoldUnicode, scaffoldMaxLength, scaffoldFixedLength, scaffoldPrecision, scaffoldScale)); }
public SqlExpressionFactory(IRelationalTypeMappingSource typeMappingSource) { _typeMappingSource = typeMappingSource; _boolTypeMapping = typeMappingSource.FindMapping(typeof(bool)); }
/// <summary> /// This is an internal API that supports the Entity Framework Core infrastructure and not subject to /// the same compatibility standards as public APIs. It may be changed or removed without notice in /// any release. You should only use it directly in your code with extreme caution and knowing that /// doing so can result in application failures when updating to a new Entity Framework Core release. /// </summary> public virtual SqlExpression Translate(SqlExpression instance, MemberInfo member, Type returnType) { Check.NotNull(member, nameof(member)); Check.NotNull(returnType, nameof(returnType)); if (typeof(Geometry).IsAssignableFrom(member.DeclaringType)) { Check.DebugAssert(instance.TypeMapping != null, "Instance must have typeMapping assigned."); var storeType = instance.TypeMapping.StoreType; var isGeography = string.Equals(storeType, "geography", StringComparison.OrdinalIgnoreCase); if (_memberToFunctionName.TryGetValue(member, out var functionName) || (!isGeography && _geometryMemberToFunctionName.TryGetValue(member, out functionName))) { var resultTypeMapping = typeof(Geometry).IsAssignableFrom(returnType) ? _typeMappingSource.FindMapping(returnType, storeType) : _typeMappingSource.FindMapping(returnType); return(_sqlExpressionFactory.Function( instance, functionName, Array.Empty <SqlExpression>(), nullable: true, instancePropagatesNullability: true, argumentsPropagateNullability: Array.Empty <bool>(), returnType, resultTypeMapping)); } if (Equals(member, _ogcGeometryType)) { var whenClauses = new List <CaseWhenClause> { new CaseWhenClause( _sqlExpressionFactory.Constant("Point"), _sqlExpressionFactory.Constant(OgcGeometryType.Point)), new CaseWhenClause( _sqlExpressionFactory.Constant("LineString"), _sqlExpressionFactory.Constant(OgcGeometryType.LineString)), new CaseWhenClause( _sqlExpressionFactory.Constant("Polygon"), _sqlExpressionFactory.Constant(OgcGeometryType.Polygon)), new CaseWhenClause( _sqlExpressionFactory.Constant("MultiPoint"), _sqlExpressionFactory.Constant(OgcGeometryType.MultiPoint)), new CaseWhenClause( _sqlExpressionFactory.Constant("MultiLineString"), _sqlExpressionFactory.Constant(OgcGeometryType.MultiLineString)), new CaseWhenClause( _sqlExpressionFactory.Constant("MultiPolygon"), _sqlExpressionFactory.Constant(OgcGeometryType.MultiPolygon)), new CaseWhenClause( _sqlExpressionFactory.Constant("GeometryCollection"), _sqlExpressionFactory.Constant(OgcGeometryType.GeometryCollection)), new CaseWhenClause( _sqlExpressionFactory.Constant("CircularString"), _sqlExpressionFactory.Constant(OgcGeometryType.CircularString)), new CaseWhenClause( _sqlExpressionFactory.Constant("CompoundCurve"), _sqlExpressionFactory.Constant(OgcGeometryType.CompoundCurve)), new CaseWhenClause( _sqlExpressionFactory.Constant("CurvePolygon"), _sqlExpressionFactory.Constant(OgcGeometryType.CurvePolygon)) }; if (isGeography) { whenClauses.Add( new CaseWhenClause( _sqlExpressionFactory.Constant("FullGlobe"), _sqlExpressionFactory.Constant((OgcGeometryType)126))); } return(_sqlExpressionFactory.Case( _sqlExpressionFactory.Function( instance, "STGeometryType", Array.Empty <SqlExpression>(), nullable: true, instancePropagatesNullability: true, argumentsPropagateNullability: Array.Empty <bool>(), typeof(string)), whenClauses.ToArray())); } if (Equals(member, _srid)) { return(_sqlExpressionFactory.Function( instance, "STSrid", nullable: true, instancePropagatesNullability: true, returnType)); } } return(null); }
public virtual RelationalTypeMapping FindMapping([NotNull] string storeTypeName) => _typeMappingSource.FindMapping(storeTypeName);
public MySqlSqlExpressionFactory(SqlExpressionFactoryDependencies dependencies) : base(dependencies) { _typeMappingSource = dependencies.TypeMappingSource; _boolTypeMapping = _typeMappingSource.FindMapping(typeof(bool)); }