mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	- 优化 子查询(多表)别名;
- 优化 IUpdate.Set 支持位运算表达式树解析;
This commit is contained in:
		@@ -502,14 +502,5 @@
 | 
				
			|||||||
            <param name="that"></param>
 | 
					            <param name="that"></param>
 | 
				
			||||||
            <returns></returns>
 | 
					            <returns></returns>
 | 
				
			||||||
        </member>
 | 
					        </member>
 | 
				
			||||||
        <member name="M:Microsoft.Extensions.DependencyInjection.FreeSqlRepositoryDependencyInjection.AddFreeRepository(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{FreeSql.FluentDataFilter},System.Reflection.Assembly[])">
 | 
					 | 
				
			||||||
            <summary>
 | 
					 | 
				
			||||||
            批量注入 Repository,可以参考代码自行调整
 | 
					 | 
				
			||||||
            </summary>
 | 
					 | 
				
			||||||
            <param name="services"></param>
 | 
					 | 
				
			||||||
            <param name="globalDataFilter"></param>
 | 
					 | 
				
			||||||
            <param name="assemblies"></param>
 | 
					 | 
				
			||||||
            <returns></returns>
 | 
					 | 
				
			||||||
        </member>
 | 
					 | 
				
			||||||
    </members>
 | 
					    </members>
 | 
				
			||||||
</doc>
 | 
					</doc>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -78,79 +78,79 @@ namespace FreeSql.Tests.PostgreSQLExpression
 | 
				
			|||||||
        public void Exp()
 | 
					        public void Exp()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            data.Add(select.Where(a => Math.Exp(1) == a.Clicks + 1).ToList());
 | 
					            data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Exp(1) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Log()
 | 
					        public void Log()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            //data.Add(select.Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).ToList());
 | 
					            //data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Log(a.Clicks + 0.5) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Log10()
 | 
					        public void Log10()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            //data.Add(select.Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).ToList());
 | 
					            //data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Log10(a.Clicks + 0.5) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Pow()
 | 
					        public void Pow()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            data.Add(select.Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).ToList());
 | 
					            data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Pow(2, a.Clicks) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Sqrt()
 | 
					        public void Sqrt()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            data.Add(select.Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList());
 | 
					            data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Sqrt(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Cos()
 | 
					        public void Cos()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            data.Add(select.Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList());
 | 
					            data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Cos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Sin()
 | 
					        public void Sin()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            data.Add(select.Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList());
 | 
					            data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Sin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Tan()
 | 
					        public void Tan()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            data.Add(select.Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList());
 | 
					            data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Tan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Acos()
 | 
					        public void Acos()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            //data.Add(select.Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList());
 | 
					            //data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Acos(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Asin()
 | 
					        public void Asin()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            //data.Add(select.Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList());
 | 
					            //data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Asin(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Atan()
 | 
					        public void Atan()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            data.Add(select.Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).ToList());
 | 
					            data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Atan(Math.Pow(2, a.Clicks)) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Atan2()
 | 
					        public void Atan2()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            data.Add(select.Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).ToList());
 | 
					            data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Atan2(2, a.Clicks) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        [Fact]
 | 
					        [Fact]
 | 
				
			||||||
        public void Truncate()
 | 
					        public void Truncate()
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            var data = new List<object>();
 | 
					            var data = new List<object>();
 | 
				
			||||||
            data.Add(select.Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).ToList());
 | 
					            data.Add(select.Where(a => a.Clicks < 100).Where(a => Math.Truncate(a.Clicks * 1.0 / 3) == a.Clicks + 1).Limit(10).ToList());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -314,6 +314,17 @@ namespace FreeSql.Tests.Sqlite
 | 
				
			|||||||
            var itemstb = select.ToDataTable();
 | 
					            var itemstb = select.ToDataTable();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void UpdateSetFlag()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var sql1 = g.sqlite.Update<TableAllType>()
 | 
				
			||||||
 | 
					                .Set(a => a.Enum2 | TableAllTypeEnumType2.f2)
 | 
				
			||||||
 | 
					                .Where(a => a.Id == 10)
 | 
				
			||||||
 | 
					                .ToSql();
 | 
				
			||||||
 | 
					            Assert.Equal(@"UPDATE ""tb_alltype"" SET ""Enum2"" = (""Enum2"" | 1), ""DateTime"" = datetime(current_timestamp,'localtime'), ""DateTimeOffSet"" = datetime(current_timestamp,'localtime'), ""DateTimeNullable"" = datetime(current_timestamp,'localtime'), ""DateTimeOffSetNullable"" = datetime(current_timestamp,'localtime') 
 | 
				
			||||||
 | 
					WHERE (""Id"" = 10)", sql1);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [Table(Name = "tb_alltype")]
 | 
					        [Table(Name = "tb_alltype")]
 | 
				
			||||||
        class TableAllType
 | 
					        class TableAllType
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,88 @@ namespace FreeSql.Tests
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    public class UnitTest4
 | 
					    public class UnitTest4
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void SelectN_SubSelectN()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.sqlite;
 | 
				
			||||||
 | 
					            var plansql1 = fsql.Select<ts_tplan, ts_tproductmode, ts_tflowversion, ts_tproflow>()
 | 
				
			||||||
 | 
					                .LeftJoin((a, b, c, d) => a.pmcode == b.pmcode)
 | 
				
			||||||
 | 
					                .LeftJoin((a, b, c, d) => b.pmcode == c.pmcode && c.isdefault == 1)
 | 
				
			||||||
 | 
					                .InnerJoin((a, b, c, d) => c.fvcode == d.fvcode)
 | 
				
			||||||
 | 
					                .ToSql((a, b, c, d) => new
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    a.billcode,
 | 
				
			||||||
 | 
					                    b.pmname,
 | 
				
			||||||
 | 
					                    d.techcode
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var plansql2 = fsql.Select<ts_tplan, ts_tproductmode, ts_tflowversion, ts_tproflow>()
 | 
				
			||||||
 | 
					                .LeftJoin((a, b, c, d) => a.pmcode == b.pmcode)
 | 
				
			||||||
 | 
					                .LeftJoin((a, b, c, d) => b.pmcode == c.pmcode && c.isdefault == 1)
 | 
				
			||||||
 | 
					                .InnerJoin((a, b, c, d) => c.fvcode == d.fvcode)
 | 
				
			||||||
 | 
					                .ToSql((a, b, c, d) => new
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    a.billcode,
 | 
				
			||||||
 | 
					                    b.pmname,
 | 
				
			||||||
 | 
					                    d.techcode,
 | 
				
			||||||
 | 
					                    planQty = fsql.Select<ts_tproduct_catering, ts_tproduct_catering_detail>()
 | 
				
			||||||
 | 
					                        .InnerJoin((e, f) => e.code == f.pccode)
 | 
				
			||||||
 | 
					                        .Where((e, f) => a.code == e.plancode)
 | 
				
			||||||
 | 
					                        .Count()
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            Assert.Equal(@"SELECT a.""billcode"" as1, b.""pmname"" as2, d.""techcode"" as3, (SELECT count(1) 
 | 
				
			||||||
 | 
					    FROM ""ts_tproduct_catering"" e 
 | 
				
			||||||
 | 
					    INNER JOIN ""ts_tproduct_catering_detail"" f ON e.""code"" = f.""pccode"" 
 | 
				
			||||||
 | 
					    WHERE (a.""code"" = e.""plancode"")) as4 
 | 
				
			||||||
 | 
					FROM ""ts_tplan"" a 
 | 
				
			||||||
 | 
					LEFT JOIN ""ts_tproductmode"" b ON a.""pmcode"" = b.""pmcode"" 
 | 
				
			||||||
 | 
					LEFT JOIN ""ts_tflowversion"" c ON b.""pmcode"" = c.""pmcode"" AND c.""isdefault"" = 1 
 | 
				
			||||||
 | 
					INNER JOIN ""ts_tproflow"" d ON c.""fvcode"" = d.""fvcode""", plansql2);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class ts_tplan
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string code { get; set; }
 | 
				
			||||||
 | 
					            public string pmcode { get; set; }
 | 
				
			||||||
 | 
					            public string billcode { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class ts_tproductmode
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string pmcode { get; set; }
 | 
				
			||||||
 | 
					            public string pmname { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class ts_tflowversion
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string fvcode { get; set; }
 | 
				
			||||||
 | 
					            public string pmcode { get; set; }
 | 
				
			||||||
 | 
					            public int isdefault { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class ts_tproflow
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string fvcode { get; set; }
 | 
				
			||||||
 | 
					            public string techcode { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class ts_tproduct_catering
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string code { get; set; }
 | 
				
			||||||
 | 
					            public string plancode { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class ts_tproduct_catering_detail
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string pccode { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class ts_tmain_record
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string code { get; set; }
 | 
				
			||||||
 | 
					            public string barcode { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class ts_tprocess_record
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public string mrcode { get; set; }
 | 
				
			||||||
 | 
					            public string barcode { get; set; }
 | 
				
			||||||
 | 
					            public string techcode { get; set; }
 | 
				
			||||||
 | 
					            public int assemres { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        class ts_lawsuit
 | 
					        class ts_lawsuit
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public Guid id { get; set; }
 | 
					            public Guid id { get; set; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1009,8 +1009,11 @@ namespace FreeSql.Internal
 | 
				
			|||||||
                                                {
 | 
					                                                {
 | 
				
			||||||
                                                    if (fsqltable1SetAlias == false)
 | 
					                                                    if (fsqltable1SetAlias == false)
 | 
				
			||||||
                                                    {
 | 
					                                                    {
 | 
				
			||||||
                                                        fsqltables[0].Alias = (argExp as LambdaExpression).Parameters.First().Name;
 | 
					 | 
				
			||||||
                                                        fsqltable1SetAlias = true;
 | 
					                                                        fsqltable1SetAlias = true;
 | 
				
			||||||
 | 
					                                                        var argExpLambda = argExp as LambdaExpression;
 | 
				
			||||||
 | 
					                                                        var fsqlTypeGenericArgs = fsqlType.GetGenericArguments();
 | 
				
			||||||
 | 
					                                                        for (var gai = 0; gai < fsqlTypeGenericArgs.Length && gai < argExpLambda.Parameters.Count; gai++)
 | 
				
			||||||
 | 
					                                                            fsqltables[gai].Alias = argExpLambda.Parameters[gai].Name;
 | 
				
			||||||
                                                    }
 | 
					                                                    }
 | 
				
			||||||
                                                }
 | 
					                                                }
 | 
				
			||||||
                                                args[a] = argExp ?? Expression.Lambda(arg3Exp).Compile().DynamicInvoke();
 | 
					                                                args[a] = argExp ?? Expression.Lambda(arg3Exp).Compile().DynamicInvoke();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -457,6 +457,11 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            var body = exp?.Body;
 | 
					            var body = exp?.Body;
 | 
				
			||||||
            var nodeType = body?.NodeType;
 | 
					            var nodeType = body?.NodeType;
 | 
				
			||||||
 | 
					            if (nodeType == ExpressionType.Convert)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                body = (body as UnaryExpression)?.Operand;
 | 
				
			||||||
 | 
					                nodeType = body?.NodeType;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            switch (nodeType)
 | 
					            switch (nodeType)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                case ExpressionType.Equal:
 | 
					                case ExpressionType.Equal:
 | 
				
			||||||
@@ -499,7 +504,7 @@ namespace FreeSql.Internal.CommonProvider
 | 
				
			|||||||
            if (body is BinaryExpression == false &&
 | 
					            if (body is BinaryExpression == false &&
 | 
				
			||||||
                nodeType != ExpressionType.Call) return this;
 | 
					                nodeType != ExpressionType.Call) return this;
 | 
				
			||||||
            var cols = new List<SelectColumnInfo>();
 | 
					            var cols = new List<SelectColumnInfo>();
 | 
				
			||||||
            var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, cols, exp, null, null);
 | 
					            var expt = _commonExpression.ExpressionWhereLambdaNoneForeignObject(null, _table, cols, body, null, null);
 | 
				
			||||||
            if (cols.Any() == false) return this;
 | 
					            if (cols.Any() == false) return this;
 | 
				
			||||||
            foreach (var col in cols)
 | 
					            foreach (var col in cols)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user