protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression) { if (methodCallExpression.Object == null && methodCallExpression.Method.DeclaringType == typeof(Enumerable) && methodCallExpression.Arguments.Count == 2 && methodCallExpression.Arguments[0] is GroupByShaperExpression groupByShaperExpression && methodCallExpression.Method.Name == nameof(Enumerable.Count)) { var selectorLambda = (LambdaExpression)methodCallExpression.Arguments[1]; if (selectorLambda.Body is SelectDistinctExpression selectDistinct) { Expression selector = ReplacingExpressionVisitor.Replace(selectDistinct.Selector.Parameters[0], groupByShaperExpression.ElementSelector, selectDistinct.Selector.Body); selector = base.Visit(selector); SqlFragmentExpression distinctFragment = base.Dependencies.SqlExpressionFactory.Fragment("DISTINCT "); RelationalTypeMapping boolTypeMapping = base.Dependencies.SqlExpressionFactory.FindMapping(typeof(bool)); var selectDistinctSql = new SelectDistinctSqlExpression(selector, distinctFragment, boolTypeMapping); return(base.Dependencies.SqlExpressionFactory.Function("COUNT", new[] { selectDistinctSql }, typeof(int))); } } return(base.VisitMethodCall(methodCallExpression)); }
protected override Expression VisitSqlFragment(SqlFragmentExpression sqlFragmentExpression) { Check.NotNull(sqlFragmentExpression, nameof(sqlFragmentExpression)); _relationalCommandBuilder.Append(sqlFragmentExpression.Sql); return(sqlFragmentExpression); }
/// <summary> /// 转换 /// </summary> /// <param name="memberExpression">成员表达式</param> /// <returns></returns> public virtual Expression Translate(MemberExpression memberExpression) { Type declaringType = memberExpression.Member.DeclaringType; if (declaringType == typeof(DateTime) || declaringType == typeof(DateTimeOffset)) { string name = memberExpression.Member.Name; if (_datePartMapping.TryGetValue(name, out string value)) { if (declaringType == typeof(DateTimeOffset) && (string.Equals(value, "HOUR") || string.Equals(value, "MINUTE"))) { // TODO: See issue#10515 // datePart = "TIMEZONE_" + datePart; return(null); } return(new SqlFunctionExpression("EXTRACT", memberExpression.Type, new Expression[2] { new SqlFragmentExpression(value), memberExpression.Expression })); } if (name == nameof(DateTime.Now)) { SqlFragmentExpression sqlDateExp = new SqlFragmentExpression("SYSDATE"); if (!(declaringType == typeof(DateTimeOffset))) { return(sqlDateExp); } return(new ExplicitCastExpression(sqlDateExp, typeof(DateTimeOffset))); } if (name == nameof(DateTime.UtcNow)) { SqlFragmentExpression sysTimeStampExp = new SqlFragmentExpression("SYSTIMESTAMP"); if (!(declaringType == typeof(DateTimeOffset))) { return(sysTimeStampExp); } return(new ExplicitCastExpression(sysTimeStampExp, typeof(DateTimeOffset))); } if (name == nameof(DateTime.Date)) { return(new SqlFunctionExpression("TRUNC", memberExpression.Type, new Expression[1] { memberExpression.Expression })); } if (name == nameof(DateTime.Today)) { return(new SqlFunctionExpression("TRUNC", memberExpression.Type, new SqlFragmentExpression[1] { new SqlFragmentExpression("SYSDATE") })); } } return(null); }
public virtual Expression Translate(MemberExpression memberExpression) { var declaringType = memberExpression.Member.DeclaringType; if (declaringType == typeof(DateTime) || declaringType == typeof(DateTimeOffset)) { var memberName = memberExpression.Member.Name; if (_datePartMapping.TryGetValue(memberName, out var datePart)) { if (declaringType == typeof(DateTimeOffset) && (string.Equals(datePart, "HOUR") || string.Equals(datePart, "MINUTE"))) { // TODO: See issue#10515 return(null); //datePart = "TIMEZONE_" + datePart; } return(new SqlFunctionExpression( "EXTRACT", memberExpression.Type, arguments: new[] { new SqlFragmentExpression(datePart), memberExpression.Expression })); } switch (memberName) { case nameof(DateTime.Now): var sysDate = new SqlFragmentExpression("SYSDATE"); return(declaringType == typeof(DateTimeOffset) ? (Expression) new ExplicitCastExpression(sysDate, typeof(DateTimeOffset)) : sysDate); case nameof(DateTime.UtcNow): var sysTimeStamp = new SqlFragmentExpression("SYSTIMESTAMP"); return(declaringType == typeof(DateTimeOffset) ? (Expression) new ExplicitCastExpression(sysTimeStamp, typeof(DateTimeOffset)) : sysTimeStamp); case nameof(DateTime.Date): return(new SqlFunctionExpression( "TRUNC", memberExpression.Type, new[] { memberExpression.Expression })); case nameof(DateTime.Today): return(new SqlFunctionExpression( "TRUNC", memberExpression.Type, new[] { new SqlFragmentExpression("SYSDATE") })); } } return(null); }
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.ApplyConfiguration(new DoctorConfiguration()); modelBuilder.HasDbFunction(FunctionsSQLServer.FSGetExpertiseMethodInfo()) .HasTranslation((args) => { var arguments = args.ToList(); arguments[1] = new SqlFragmentExpression( (string)((SqlConstantExpression)arguments.Last()).Value ); return(SqlFunctionExpression.Create("dbo.FSGetExpertise", arguments, typeof(int), null)); }); modelBuilder.HasDbFunction(FunctionsSQLServer.CharIndexToMethodInfo()) .HasTranslation((args) => { var arguments = args.ToList(); arguments[1] = new SqlFragmentExpression( (string)((SqlConstantExpression)arguments.Last()).Value ); return(SqlFunctionExpression.Create("CHARINDEX", arguments, typeof(int), null)); }); # region FunctionSQLServer //SET ANSI_NULLS ON //GO //SET QUOTED_IDENTIFIER ON //GO //-- ============================================= //--Author: < Fúlvio Cezar Canducci Dias > //--Create date: < 04 / 09 / 2020 > //--Description: < Expertise > //-- ============================================= //ALTER FUNCTION dbo.FSGetExpertise //( // @Value nvarchar(450), // @Field nvarchar(450) //) //RETURNS INT //AS //BEGIN // RETURN CHARINDEX(@Value, @Field COLLATE Latin1_General_CI_AS); //END //GO #endregion }
/// <summary> /// Applies configuration so that we can user <see cref="JsonFunctions.CastToDouble(string)"/> /// </summary> /// <param name="modelBuilder"></param> /// <returns></returns> public static DbFunctionBuilder ApplyJsonCastToDouble(this ModelBuilder modelBuilder) { if (modelBuilder is null) { throw new ArgumentNullException(nameof(modelBuilder)); } return(modelBuilder.HasDbFunction(typeof(JsonFunctions).GetMethod(nameof(JsonFunctions.CastToDouble))) .HasTranslation(args => { var float32 = new SqlFragmentExpression("float"); var convertArgs = new SqlExpression[] { float32 }.Concat(args); return SqlFunctionExpression.Create("Convert", convertArgs, typeof(double?), null); }) .HasSchema(string.Empty)); }
public static void EnableSqlServerDateDIFF(this ModelBuilder builder) { builder.HasDbFunction(typeof(EFCore) .GetMethod(nameof(EFCore.DateDiff))) .HasTranslation(args => { var arguments = args.ToList(); arguments[0] = new SqlFragmentExpression(((ConstantExpression)arguments.First()).Value.ToString()); return new SqlFunctionExpression( "DATEDIFF", typeof(int), arguments); }); }
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.HasDbFunction(typeof(DbUtility) .GetMethod(nameof(DbUtility.DateDiff))) .HasTranslation(args => { var newArgs = args.ToArray(); newArgs[0] = new SqlFragmentExpression((string)((ConstantExpression)newArgs[0]).Value); return(new SqlFunctionExpression( "DATEDIFF", typeof(int), newArgs)); }); }
/// <summary> /// Applies configuration so that we can user <see cref="JsonFunctions.CastToDouble(string)"/> /// </summary> /// <param name="modelBuilder"></param> /// <returns></returns> public static DbFunctionBuilder ApplyJsonCastToDouble(this ModelBuilder modelBuilder) { if (modelBuilder is null) { throw new ArgumentNullException(nameof(modelBuilder)); } return(modelBuilder.HasDbFunction(typeof(JsonFunctions).GetMethod(nameof(JsonFunctions.CastToDouble))) .HasTranslation(args => { var float32 = new SqlFragmentExpression("float"); var convertArgs = new SqlExpression[] { float32 }.Concat(args); #if NET5_0_OR_GREATER return new SqlFunctionExpression("Convert", convertArgs, nullable: true, argumentsPropagateNullability: convertArgs.Select(x => true), typeof(double?), null); #else return SqlFunctionExpression.Create("Convert", convertArgs, typeof(double?), null); #endif }) .HasSchema(string.Empty)); }
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity <Evento>(); modelBuilder .HasDbFunction(typeof(Funcoes).GetMethod(nameof(Funcoes.DateDIFF))) .HasTranslation(p => { var args = p.ToList(); args[0] = new SqlFragmentExpression((string)((ConstantExpression)args.First()).Value); return(new SqlFunctionExpression( "DATEDIFF", typeof(int), args)); }); }
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder .HasDbFunction(typeof(Funcoes) .GetMethod(nameof(Funcoes.ContainsIn))) .HasTranslation(args => { var arguments = args.ToList(); var a = (string)((SqlConstantExpression)arguments[0]).Value; arguments[0] = new SqlFragmentExpression(a); return(SqlFunctionExpression.Create("CONTAINS", arguments, typeof(bool), null)); }); modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); }
public virtual SqlExpression ApplyTypeMapping(SqlExpression sqlExpression, RelationalTypeMapping typeMapping) { if (sqlExpression == null || sqlExpression.TypeMapping != null) { return(sqlExpression); } return(sqlExpression switch { CaseExpression e => ApplyTypeMappingOnCase(e, typeMapping), LikeExpression e => ApplyTypeMappingOnLike(e), SqlBinaryExpression e => ApplyTypeMappingOnSqlBinary(e, typeMapping), SqlUnaryExpression e => ApplyTypeMappingOnSqlUnary(e, typeMapping), SqlConstantExpression e => e.ApplyTypeMapping(typeMapping), SqlFragmentExpression e => e, SqlFunctionExpression e => e.ApplyTypeMapping(typeMapping), SqlParameterExpression e => e.ApplyTypeMapping(typeMapping), _ => sqlExpression });
/// <inheritdoc /> public virtual SqlExpression ApplyTypeMapping(SqlExpression sqlExpression, RelationalTypeMapping typeMapping) { #pragma warning disable IDE0046 // Convert to conditional expression if (sqlExpression == null #pragma warning restore IDE0046 // Convert to conditional expression || sqlExpression.TypeMapping != null) { return(sqlExpression); } return(sqlExpression switch { CaseExpression e => ApplyTypeMappingOnCase(e, typeMapping), CollateExpression e => ApplyTypeMappingOnCollate(e, typeMapping), LikeExpression e => ApplyTypeMappingOnLike(e), SqlBinaryExpression e => ApplyTypeMappingOnSqlBinary(e, typeMapping), SqlUnaryExpression e => ApplyTypeMappingOnSqlUnary(e, typeMapping), SqlConstantExpression e => e.ApplyTypeMapping(typeMapping), SqlFragmentExpression e => e, SqlFunctionExpression e => e.ApplyTypeMapping(typeMapping), SqlParameterExpression e => e.ApplyTypeMapping(typeMapping), _ => sqlExpression });
/// <summary> /// Visits the children of the sql fragent expression. /// </summary> /// <param name="sqlFragmentExpression"> The expression to visit. </param> /// <returns> The modified expression, if it or any subexpression was modified; otherwise, returns the original expression. </returns> protected abstract Expression VisitSqlFragment([NotNull] SqlFragmentExpression sqlFragmentExpression);
protected override Expression VisitSqlFragment(SqlFragmentExpression sqlFragmentExpression) { _relationalCommandBuilder.Append(sqlFragmentExpression.Sql); return(sqlFragmentExpression); }
public SelectDistinctSqlExpression(Expression selector, SqlFragmentExpression distinctFragment, RelationalTypeMapping typeMapping) : base(typeof(bool), typeMapping) { Selector = selector; _distinctFragment = distinctFragment; }
protected abstract Expression VisitSqlFragment(SqlFragmentExpression sqlFragmentExpression);
protected override Expression VisitSqlFragment(SqlFragmentExpression sqlFragmentExpression) => sqlFragmentExpression;
protected override Expression VisitSqlFragment(SqlFragmentExpression sqlFragmentExpression) { return(sqlFragmentExpression); }
protected override Expression VisitSqlFragment(SqlFragmentExpression sqlFragmentExpression) { Check.NotNull(sqlFragmentExpression, nameof(sqlFragmentExpression)); return(sqlFragmentExpression); }
protected override Expression VisitSqlFragment(SqlFragmentExpression x) { return(x); }