mirror of
				https://github.com/nsnail/FreeSql.git
				synced 2025-11-04 17:20:49 +08:00 
			
		
		
		
	- 修复 DbSet.Where 表达式解析报错的问题;#216
This commit is contained in:
		@@ -22,9 +22,41 @@ namespace FreeSql.Tests
 | 
			
		||||
    public class UnitTest3
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
        public class Song23
 | 
			
		||||
        {
 | 
			
		||||
            public long Id { get; set; }
 | 
			
		||||
            public string Name { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public class Author23
 | 
			
		||||
        {
 | 
			
		||||
            public long Id { get; set; }
 | 
			
		||||
            public long SongId { get; set; }
 | 
			
		||||
            public string Name { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public class TestDbContext : DbContext
 | 
			
		||||
        {
 | 
			
		||||
            public TestDbContext(IFreeSql orm) : base(orm, null)
 | 
			
		||||
            {
 | 
			
		||||
            }
 | 
			
		||||
            public DbSet<Song23> Songs { get; set; }
 | 
			
		||||
            public DbSet<Author23> Authors { get; set; }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        [Fact]
 | 
			
		||||
        public void Test03()
 | 
			
		||||
        {
 | 
			
		||||
            var context = new TestDbContext(g.sqlite);
 | 
			
		||||
 | 
			
		||||
            var sql = context.Songs
 | 
			
		||||
                .Where(a =>
 | 
			
		||||
                    context.Authors
 | 
			
		||||
                        //.Select  //加上这句就不报错,不加上报 variable 'a' of type 'Song' referenced from scope '', but it is not defined
 | 
			
		||||
                        .Where(b => b.SongId == a.Id)
 | 
			
		||||
                        .Any())
 | 
			
		||||
                .ToSql(a => a.Name);
 | 
			
		||||
 | 
			
		||||
            //using (var conn = new SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=webchat-abc;Pooling=true;Max Pool Size=13"))
 | 
			
		||||
            //{
 | 
			
		||||
            //    conn.Open();
 | 
			
		||||
 
 | 
			
		||||
@@ -771,6 +771,32 @@ namespace FreeSql.Internal
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                }
 | 
			
		||||
                                            }
 | 
			
		||||
                                            if (new[] { "Where", "WhereIf" }.Contains(exp3tmpCall.Method.Name) && exp3tmpCall.Object != null)
 | 
			
		||||
                                            {
 | 
			
		||||
                                                //这段特别兼容 DbSet.Where 表达式解析 #216
 | 
			
		||||
                                                var exp3tmpTestCall = Expression.Call(exp3tmpCall.Object, exp3tmpCall.Method, exp3tmpCall.Arguments.Select(a =>
 | 
			
		||||
                                                {
 | 
			
		||||
                                                    var a2 = a;
 | 
			
		||||
                                                    if (a2.NodeType == ExpressionType.Quote) a2 = (a as UnaryExpression)?.Operand;
 | 
			
		||||
                                                    if (a2?.NodeType == ExpressionType.Lambda)
 | 
			
		||||
                                                    {
 | 
			
		||||
                                                        var alambda = a2 as LambdaExpression;
 | 
			
		||||
                                                        if (alambda.ReturnType == typeof(bool))
 | 
			
		||||
                                                            return Expression.Constant(null, a.Type);// Expression.Lambda(Expression.Constant(true), alambda.Parameters);
 | 
			
		||||
                                                    }
 | 
			
		||||
                                                    return a;
 | 
			
		||||
                                                    //if (a.Type == typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(exp3tmp.Type.GetGenericArguments()[0], typeof(bool))))
 | 
			
		||||
                                                    //    return Expression.Lambda(Expression.Constant(true), 
 | 
			
		||||
                                                }).ToArray());
 | 
			
		||||
                                                fsql = Expression.Lambda(exp3tmpTestCall).Compile().DynamicInvoke();
 | 
			
		||||
                                                var fsqlFindMethod = fsql.GetType().GetMethod(exp3tmpCall.Method.Name, exp3tmpCall.Arguments.Select(a => a.Type).ToArray());
 | 
			
		||||
                                                if (fsqlFindMethod == null)
 | 
			
		||||
                                                    throw new Exception($"无法解析表达式方法 {exp3tmpCall.Method.Name}");
 | 
			
		||||
                                                var exp3StackOld = exp3Stack;
 | 
			
		||||
                                                exp3Stack = new Stack<Expression>();
 | 
			
		||||
                                                exp3Stack.Push(Expression.Call(Expression.Constant(fsql), fsqlFindMethod, exp3tmpCall.Arguments));
 | 
			
		||||
                                                while (exp3StackOld.Any()) exp3Stack.Push(exp3StackOld.Pop());
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                        if (fsql == null) fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke();
 | 
			
		||||
                                        fsqlType = fsql?.GetType();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user