- 修复 DbSet.Where 表达式解析报错的问题;#216

This commit is contained in:
28810 2020-02-27 12:54:43 +08:00
parent 96f3957b98
commit 761b6e0068
2 changed files with 58 additions and 0 deletions

View File

@ -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();

View File

@ -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();