- 增加 SqlExt 常用开窗函数的自定义表达式解析;

This commit is contained in:
28810
2020-06-14 10:38:53 +08:00
parent 7a2000a29e
commit 72cccffc30
4 changed files with 117 additions and 4 deletions

View File

@ -1,5 +1,6 @@
using FreeSql.DataAnnotations;
using System;
using System.Text;
using System.Threading;
[ExpressionCall]
@ -39,4 +40,67 @@ public static class FreeSqlGlobalExpressionCallExtensions
expContext.Value.Result = $"{expContext.Value.ParsedContent["that"]} >= {expContext.Value.ParsedContent["start"]} and {expContext.Value.ParsedContent["that"]} < {expContext.Value.ParsedContent["end"]}";
return false;
}
}
namespace FreeSql
{
[ExpressionCall]
public static class SqlExt
{
public static ThreadLocal<ExpressionCallContext> expContext = new ThreadLocal<ExpressionCallContext>();
static ThreadLocal<StringBuilder> expSb = new ThreadLocal<StringBuilder>();
static ThreadLocal<bool> expSbIsOrderBy = new ThreadLocal<bool>();
public static ISqlOver<long> Rank() => Over<long>("RANK()");
public static ISqlOver<long> DenseRank() => Over<long>("DENSE_RANK()");
public static ISqlOver<long> Count() => Over<long>("COUNT()");
public static ISqlOver<decimal> Sum(object column) => Over<decimal>($"Sum({expContext.Value.ParsedContent["column"]})");
public static ISqlOver<decimal> Avg() => Over<decimal>($"AVG({expContext.Value.ParsedContent["column"]})");
public static ISqlOver<T> Max<T>(T column) => Over<T>($"MAX({expContext.Value.ParsedContent["column"]})");
public static ISqlOver<T> Min<T>(T column) => Over<T>($"MIN({expContext.Value.ParsedContent["column"]})");
public static ISqlOver<long> RowNumber() => Over<long>("ROW_NUMBER()");
#region .. over([partition by ..] order by ...)
static ISqlOver<TValue> Over<TValue>(string sqlFunc)
{
expSb.Value = new StringBuilder();
expSbIsOrderBy.Value = false;
expSb.Value.Append($"{sqlFunc} ");
return null;
}
public static ISqlOver<TValue> Over<TValue>(this ISqlOver<TValue> that)
{
expSb.Value.Append("OVER(");
return that;
}
public static ISqlOver<TValue> PartitionBy<TValue>(this ISqlOver<TValue> that, object column)
{
expSb.Value.Append("PARTITION BY ").Append(expContext.Value.ParsedContent["column"]).Append(",");
return that;
}
public static ISqlOver<TValue> OrderBy<TValue>(this ISqlOver<TValue> that, object column) => OrderBy(that, false);
public static ISqlOver<TValue> OrderByDescending<TValue>(this ISqlOver<TValue> that, object column) => OrderBy(that, true);
static ISqlOver<TValue> OrderBy<TValue>(this ISqlOver<TValue> that, bool isDesc)
{
var sb = expSb.Value;
if (expSbIsOrderBy.Value == false)
{
sb.Append("ORDER BY ");
expSbIsOrderBy.Value = true;
}
sb.Append(expContext.Value.ParsedContent["column"]);
if (isDesc) sb.Append(" desc");
sb.Append(",");
return that;
}
public static TValue ToValue<TValue>(this ISqlOver<TValue> that)
{
var sb = expSb.Value.ToString().TrimEnd(',');
expSb.Value.Clear();
expContext.Value.Result = $"{sb})";
return default;
}
public interface ISqlOver<TValue> { }
#endregion
}
}