diff --git a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs index 1d90c5595..8d1d11fe3 100644 --- a/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs +++ b/FreeSql.Tests/FreeSql.Tests/UnitTest3.cs @@ -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 Songs { get; set; } + public DbSet 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(); diff --git a/FreeSql/Internal/CommonExpression.cs b/FreeSql/Internal/CommonExpression.cs index 9a9b7a86d..3dc16e122 100644 --- a/FreeSql/Internal/CommonExpression.cs +++ b/FreeSql/Internal/CommonExpression.cs @@ -771,6 +771,32 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc) } } } + 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(); + 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();