From 72cccffc30fff26f90c0b2df2a9d4aa9b5c95880 Mon Sep 17 00:00:00 2001
From: 28810 <28810@YEXIANGQIN>
Date: Sun, 14 Jun 2020 10:38:53 +0800
Subject: [PATCH] =?UTF-8?q?-=20=E5=A2=9E=E5=8A=A0=20SqlExt=20=E5=B8=B8?=
=?UTF-8?q?=E7=94=A8=E5=BC=80=E7=AA=97=E5=87=BD=E6=95=B0=E7=9A=84=E8=87=AA?=
=?UTF-8?q?=E5=AE=9A=E4=B9=89=E8=A1=A8=E8=BE=BE=E5=BC=8F=E8=A7=A3=E6=9E=90?=
=?UTF-8?q?=EF=BC=9B?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FreeSql.DbContext/FreeSql.DbContext.xml | 16 +++++
FreeSql.Tests/FreeSql.Tests/UnitTest3.cs | 17 +++++
.../FreeSqlGlobalExpressionCallExtensions.cs | 64 +++++++++++++++++++
FreeSql/Internal/CommonExpression.cs | 24 +++++--
4 files changed, 117 insertions(+), 4 deletions(-)
diff --git a/FreeSql.DbContext/FreeSql.DbContext.xml b/FreeSql.DbContext/FreeSql.DbContext.xml
index 132d875e..4854f49c 100644
--- a/FreeSql.DbContext/FreeSql.DbContext.xml
+++ b/FreeSql.DbContext/FreeSql.DbContext.xml
@@ -125,6 +125,13 @@
清空状态数据
+
+
+ 根据 lambda 条件删除数据
+
+
+
+
添加
@@ -479,5 +486,14 @@
+
+
+ 批量注入 Repository,可以参考代码自行调整
+
+
+
+
+
+
diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs
index 28ea2939..762fdaa9 100644
--- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs
+++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs
@@ -155,6 +155,23 @@ namespace FreeSql.Tests
[Fact]
public void Test03()
{
+ var sqlextOver = g.sqlserver.Select()
+ .InnerJoin((a, b) => b.Id == a.Id)
+ .ToSql((a, b) => new
+ {
+ Id = a.Id,
+ EdiId = b.Id,
+ over1 = SqlExt.Rank().Over().OrderBy(a.Id).OrderByDescending(b.EdiId).ToValue()
+ });
+ var sqlextOverToList = g.sqlserver.Select()
+ .InnerJoin((a, b) => b.Id == a.Id)
+ .ToList((a, b) => new
+ {
+ Id = a.Id,
+ EdiId = b.Id,
+ over1 = SqlExt.Rank().Over().OrderBy(a.Id).OrderByDescending(b.EdiId).ToValue()
+ });
+
var tttrule = 8;
var tttid = new long[] { 18, 19, 4017 };
g.sqlserver.Update().Set(it => it.SongId == (short)(it.SongId & ~tttrule)).Where(it => (it.SongId & tttrule) == tttrule && !tttid.Contains(it.Id)).ExecuteAffrows();
diff --git a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs
index 63c48c4e..c8de533c 100644
--- a/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs
+++ b/FreeSql/Extensions/FreeSqlGlobalExpressionCallExtensions.cs
@@ -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 expContext = new ThreadLocal();
+ static ThreadLocal expSb = new ThreadLocal();
+ static ThreadLocal expSbIsOrderBy = new ThreadLocal();
+
+ public static ISqlOver Rank() => Over("RANK()");
+ public static ISqlOver DenseRank() => Over("DENSE_RANK()");
+ public static ISqlOver Count() => Over("COUNT()");
+ public static ISqlOver Sum(object column) => Over($"Sum({expContext.Value.ParsedContent["column"]})");
+ public static ISqlOver Avg() => Over($"AVG({expContext.Value.ParsedContent["column"]})");
+ public static ISqlOver Max(T column) => Over($"MAX({expContext.Value.ParsedContent["column"]})");
+ public static ISqlOver Min(T column) => Over($"MIN({expContext.Value.ParsedContent["column"]})");
+ public static ISqlOver RowNumber() => Over("ROW_NUMBER()");
+
+ #region .. over([partition by ..] order by ...)
+ static ISqlOver Over(string sqlFunc)
+ {
+ expSb.Value = new StringBuilder();
+ expSbIsOrderBy.Value = false;
+ expSb.Value.Append($"{sqlFunc} ");
+ return null;
+ }
+ public static ISqlOver Over(this ISqlOver that)
+ {
+ expSb.Value.Append("OVER(");
+ return that;
+ }
+ public static ISqlOver PartitionBy(this ISqlOver that, object column)
+ {
+ expSb.Value.Append("PARTITION BY ").Append(expContext.Value.ParsedContent["column"]).Append(",");
+ return that;
+ }
+ public static ISqlOver OrderBy(this ISqlOver that, object column) => OrderBy(that, false);
+ public static ISqlOver OrderByDescending(this ISqlOver that, object column) => OrderBy(that, true);
+ static ISqlOver OrderBy(this ISqlOver 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(this ISqlOver that)
+ {
+ var sb = expSb.Value.ToString().TrimEnd(',');
+ expSb.Value.Clear();
+ expContext.Value.Result = $"{sb})";
+ return default;
+ }
+ public interface ISqlOver { }
+ #endregion
+ }
}
\ No newline at end of file
diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs
index c870a2f9..e620643c 100644
--- a/FreeSql/Internal/CommonExpression.cs
+++ b/FreeSql/Internal/CommonExpression.cs
@@ -627,8 +627,11 @@ namespace FreeSql.Internal
};
var exp3MethodParams = exp3.Method.GetParameters();
var dbParamsIndex = tsc.dbParams?.Count;
- ecc.RawExpression.Add(exp3MethodParams[0].Name, exp3.Arguments[0]);
- ecc.ParsedContent.Add(exp3MethodParams[0].Name, exp3MethodParams[0].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null : ExpressionLambdaToSql(exp3.Arguments[0], tsc));
+ if (exp3MethodParams.Any())
+ {
+ ecc.RawExpression.Add(exp3MethodParams[0].Name, exp3.Arguments[0]);
+ ecc.ParsedContent.Add(exp3MethodParams[0].Name, exp3MethodParams[0].GetCustomAttributes(typeof(RawValueAttribute), true).Any() ? null : ExpressionLambdaToSql(exp3.Arguments[0], tsc));
+ }
if (tsc.dbParams?.Count > dbParamsIndex) ecc.DbParameter = tsc.dbParams.Last();
List oldDbParams = tsc.SetDbParamsReturnOld(null);
for (var a = 1; a < exp3.Arguments.Count; a++)
@@ -646,7 +649,20 @@ namespace FreeSql.Internal
{
var eccContent = ecc.ParsedContent[exp3MethodParams[a].Name];
if (eccContent == null)
- exp3InvokeParams[a] = Expression.Lambda(exp3.Arguments[a]).Compile().DynamicInvoke();
+ {
+ var isdyInvoke = true;
+ if (exp3.Arguments[a].NodeType == ExpressionType.Call) //判断如果参数也是标记 ExpressionCall
+ {
+ var exp3ArgsACallExp = exp3.Arguments[a] as MethodCallExpression;
+ if (exp3ArgsACallExp.Object == null && (
+ _dicTypeExistsExpressionCallAttribute.GetOrAdd(exp3ArgsACallExp.Method.DeclaringType, dttp => dttp.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any()) ||
+ exp3ArgsACallExp.Method.GetCustomAttributes(typeof(ExpressionCallAttribute), true).Any()
+ ))
+ isdyInvoke = false;
+ }
+ if (isdyInvoke)
+ exp3InvokeParams[a] = Expression.Lambda(exp3.Arguments[a]).Compile().DynamicInvoke();
+ }
else if (exp3.Arguments[a].IsParameter())
exp3InvokeParams[a] = exp3.Arguments[a].Type.CreateInstanceGetDefaultValue();
else
@@ -668,7 +684,7 @@ namespace FreeSql.Internal
{
var sqlRet = exp3.Method.Invoke(null, exp3InvokeParams);
if (string.IsNullOrEmpty(ecc.Result) && sqlRet is string) ecc.Result = string.Concat(sqlRet);
- if (string.IsNullOrEmpty(ecc.Result)) ecc.Result = ecc.ParsedContent[exp3MethodParams[0].Name];
+ if (string.IsNullOrEmpty(ecc.Result) && exp3MethodParams.Any()) ecc.Result = ecc.ParsedContent[exp3MethodParams[0].Name];
if (ecc.UserParameters?.Any() == true) tsc.dbParams?.AddRange(ecc.UserParameters);
return ecc.Result;
}