mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 优化 表达式树三元表达式解析,当 Test 为变量时不解析成 case when end;
This commit is contained in:
		@@ -1,4 +1,5 @@
 | 
				
			|||||||
using System;
 | 
					using FreeSql.DataAnnotations;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Diagnostics;
 | 
					using System.Diagnostics;
 | 
				
			||||||
using System.Text;
 | 
					using System.Text;
 | 
				
			||||||
@@ -11,6 +12,98 @@ namespace FreeSql.Tests
 | 
				
			|||||||
    public class UnitTest4
 | 
					    public class UnitTest4
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public record ts_iif(Guid id, string title);
 | 
				
			||||||
 | 
					        [Fact]
 | 
				
			||||||
 | 
					        public void IIF()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var fsql = g.sqlserver;
 | 
				
			||||||
 | 
					            fsql.Delete<ts_iif>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var id = Guid.NewGuid();
 | 
				
			||||||
 | 
					            fsql.Insert(new ts_iif(id, "001")).ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var item = fsql.Select<ts_iif>().Where(a => a.id == (id != Guid.NewGuid() ? id : a.id)).First();
 | 
				
			||||||
 | 
					            Assert.Equal(id, item.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var item2 = fsql.Select<ts_iif>().First(a => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                xxx = id != Guid.NewGuid() ? a.id : Guid.Empty
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            Assert.Equal(id, item2.xxx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            fsql.Delete<ts_iif>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            fsql.Delete<ts_iif_type>().Where("1=1").ExecuteAffrows();
 | 
				
			||||||
 | 
					            var typeid = Guid.NewGuid();
 | 
				
			||||||
 | 
					            fsql.Insert(new ts_iif_type { id = typeid, name = "type001" }).ExecuteAffrows();
 | 
				
			||||||
 | 
					            fsql.Insert(new ts_iif_topic { id = id, typeid = typeid, title = "title001" }).ExecuteAffrows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var more1 = true;
 | 
				
			||||||
 | 
					            var more2 = (bool?)true;
 | 
				
			||||||
 | 
					            var more3 = (bool?)false;
 | 
				
			||||||
 | 
					            var more4 = (bool?)null;
 | 
				
			||||||
 | 
					            var moreitem = fsql.Select<ts_iif_topic>().First(a => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                a.id,
 | 
				
			||||||
 | 
					                a.title,
 | 
				
			||||||
 | 
					                a.type
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            Assert.Equal(id, moreitem.id);
 | 
				
			||||||
 | 
					            Assert.Equal("title001", moreitem.title);
 | 
				
			||||||
 | 
					            Assert.Equal(typeid, moreitem.type.id);
 | 
				
			||||||
 | 
					            Assert.Equal("type001", moreitem.type.name);
 | 
				
			||||||
 | 
					            var moreitem1 = fsql.Select<ts_iif_topic>().First(a => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                a.id,
 | 
				
			||||||
 | 
					                a.title,
 | 
				
			||||||
 | 
					                type1 = more1 == true ? a.type : null,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            Assert.Equal(id, moreitem1.id);
 | 
				
			||||||
 | 
					            Assert.Equal("title001", moreitem1.title);
 | 
				
			||||||
 | 
					            Assert.Equal(typeid, moreitem1.type1.id);
 | 
				
			||||||
 | 
					            Assert.Equal("type001", moreitem1.type1.name);
 | 
				
			||||||
 | 
					            var moreitem2 = fsql.Select<ts_iif_topic>().First(a => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                a.id,
 | 
				
			||||||
 | 
					                a.title,
 | 
				
			||||||
 | 
					                type2 = more2 == true ? a.type : null,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            Assert.Equal(id, moreitem2.id);
 | 
				
			||||||
 | 
					            Assert.Equal("title001", moreitem2.title);
 | 
				
			||||||
 | 
					            Assert.Equal(typeid, moreitem2.type2.id);
 | 
				
			||||||
 | 
					            Assert.Equal("type001", moreitem2.type2.name);
 | 
				
			||||||
 | 
					            var moreitem3 = fsql.Select<ts_iif_topic>().First(a => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                a.id,
 | 
				
			||||||
 | 
					                a.title,
 | 
				
			||||||
 | 
					                type3 = more3 == true ? a.type : null,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            Assert.Equal(id, moreitem3.id);
 | 
				
			||||||
 | 
					            Assert.Equal("title001", moreitem3.title);
 | 
				
			||||||
 | 
					            Assert.Null(moreitem3.type3);
 | 
				
			||||||
 | 
					            var moreitem4 = fsql.Select<ts_iif_topic>().First(a => new
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                a.id,
 | 
				
			||||||
 | 
					                a.title,
 | 
				
			||||||
 | 
					                type4 = more4 == true ? a.type : null,
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            Assert.Equal(id, moreitem4.id);
 | 
				
			||||||
 | 
					            Assert.Equal("title001", moreitem4.title);
 | 
				
			||||||
 | 
					            Assert.Null(moreitem4.type4);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class ts_iif_topic
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public Guid id { get; set; }
 | 
				
			||||||
 | 
					            public Guid typeid { get; set; }
 | 
				
			||||||
 | 
					            [Navigate(nameof(typeid))]
 | 
				
			||||||
 | 
					            public ts_iif_type type { get; set; }
 | 
				
			||||||
 | 
					            public string title { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        class ts_iif_type
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            public Guid id { get; set; }
 | 
				
			||||||
 | 
					            public string name { get; set; }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public record ts_record(DateTime Date, int TemperatureC, int TemperatureF, string Summary)
 | 
					        public record ts_record(DateTime Date, int TemperatureC, int TemperatureF, string Summary)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public ts_record parent { get; set; }
 | 
					            public ts_record parent { get; set; }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -70,6 +70,11 @@ namespace FreeSql.Internal
 | 
				
			|||||||
                    else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName));
 | 
					                    else if (index == ReadAnonymousFieldAsCsName && string.IsNullOrEmpty(parent.CsName) == false) field.Append(_common.FieldAsAlias(parent.CsName));
 | 
				
			||||||
                    if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type;
 | 
					                    if (parent.CsType == null && exp.Type.IsValueType) parent.CsType = exp.Type;
 | 
				
			||||||
                    return false;
 | 
					                    return false;
 | 
				
			||||||
 | 
					                case ExpressionType.Conditional:
 | 
				
			||||||
 | 
					                    var condExp = exp as ConditionalExpression;
 | 
				
			||||||
 | 
					                    if (condExp.Test.IsParameter() == false) return ReadAnonymousField(_tables, field, parent, ref index,
 | 
				
			||||||
 | 
					                        (bool)Expression.Lambda(condExp.Test).Compile().DynamicInvoke() ? condExp.IfTrue : condExp.IfFalse, select, diymemexp, whereGlobalFilter, findIncludeMany, isAllDtoMap);
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
                case ExpressionType.Call:
 | 
					                case ExpressionType.Call:
 | 
				
			||||||
                    var callExp = exp as MethodCallExpression;
 | 
					                    var callExp = exp as MethodCallExpression;
 | 
				
			||||||
                    //处理自定义SQL语句,如: ToList(new { 
 | 
					                    //处理自定义SQL语句,如: ToList(new { 
 | 
				
			||||||
@@ -703,11 +708,28 @@ namespace FreeSql.Internal
 | 
				
			|||||||
                case ExpressionType.Conditional:
 | 
					                case ExpressionType.Conditional:
 | 
				
			||||||
                    var condExp = exp as ConditionalExpression;
 | 
					                    var condExp = exp as ConditionalExpression;
 | 
				
			||||||
                    var conditionalTestOldMapType = tsc.SetMapTypeReturnOld(null);
 | 
					                    var conditionalTestOldMapType = tsc.SetMapTypeReturnOld(null);
 | 
				
			||||||
                    var conditionalTestSql = ExpressionLambdaToSql(condExp.Test, tsc);
 | 
					                    if (condExp.Test.IsParameter())
 | 
				
			||||||
                    tsc.SetMapTypeReturnOld(conditionalTestOldMapType);
 | 
					                    {
 | 
				
			||||||
                    var conditionalSql = _common.IIF(conditionalTestSql, ExpressionLambdaToSql(condExp.IfTrue, tsc), ExpressionLambdaToSql(condExp.IfFalse, tsc));
 | 
					                        var conditionalTestSql = ExpressionLambdaToSql(condExp.Test, tsc);
 | 
				
			||||||
                    tsc.SetMapTypeReturnOld(null);
 | 
					                        tsc.SetMapTypeReturnOld(conditionalTestOldMapType);
 | 
				
			||||||
                    return conditionalSql;
 | 
					                        var conditionalSql = _common.IIF(conditionalTestSql, ExpressionLambdaToSql(condExp.IfTrue, tsc), ExpressionLambdaToSql(condExp.IfFalse, tsc));
 | 
				
			||||||
 | 
					                        tsc.SetMapTypeReturnOld(null);
 | 
				
			||||||
 | 
					                        return conditionalSql;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if ((bool)Expression.Lambda(condExp.Test).Compile().DynamicInvoke())
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        tsc.SetMapTypeReturnOld(conditionalTestOldMapType);
 | 
				
			||||||
 | 
					                        var conditionalSql = ExpressionLambdaToSql(condExp.IfTrue, tsc);
 | 
				
			||||||
 | 
					                        tsc.SetMapTypeReturnOld(null);
 | 
				
			||||||
 | 
					                        return conditionalSql;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        tsc.SetMapTypeReturnOld(conditionalTestOldMapType);
 | 
				
			||||||
 | 
					                        var conditionalSql = ExpressionLambdaToSql(condExp.IfFalse, tsc);
 | 
				
			||||||
 | 
					                        tsc.SetMapTypeReturnOld(null);
 | 
				
			||||||
 | 
					                        return conditionalSql;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                case ExpressionType.Call:
 | 
					                case ExpressionType.Call:
 | 
				
			||||||
                    tsc.mapType = null;
 | 
					                    tsc.mapType = null;
 | 
				
			||||||
                    var exp3 = exp as MethodCallExpression;
 | 
					                    var exp3 = exp as MethodCallExpression;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user