Skip to content

Commit 761b6e0

Browse files
2881028810
authored andcommitted
- 修复 DbSet.Where 表达式解析报错的问题;#216
1 parent 96f3957 commit 761b6e0

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

FreeSql.Tests/FreeSql.Tests/UnitTest3.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,41 @@ namespace FreeSql.Tests
2222
public class UnitTest3
2323
{
2424

25+
public class Song23
26+
{
27+
public long Id { get; set; }
28+
public string Name { get; set; }
29+
}
30+
31+
public class Author23
32+
{
33+
public long Id { get; set; }
34+
public long SongId { get; set; }
35+
public string Name { get; set; }
36+
}
37+
38+
public class TestDbContext : DbContext
39+
{
40+
public TestDbContext(IFreeSql orm) : base(orm, null)
41+
{
42+
}
43+
public DbSet<Song23> Songs { get; set; }
44+
public DbSet<Author23> Authors { get; set; }
45+
}
46+
2547
[Fact]
2648
public void Test03()
2749
{
50+
var context = new TestDbContext(g.sqlite);
51+
52+
var sql = context.Songs
53+
.Where(a =>
54+
context.Authors
55+
//.Select //加上这句就不报错,不加上报 variable 'a' of type 'Song' referenced from scope '', but it is not defined
56+
.Where(b => b.SongId == a.Id)
57+
.Any())
58+
.ToSql(a => a.Name);
59+
2860
//using (var conn = new SqlConnection("Data Source=.;Integrated Security=True;Initial Catalog=webchat-abc;Pooling=true;Max Pool Size=13"))
2961
//{
3062
// conn.Open();

FreeSql/Internal/CommonExpression.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,32 @@ public string ExpressionLambdaToSql(Expression exp, ExpTSC tsc)
771771
}
772772
}
773773
}
774+
if (new[] { "Where", "WhereIf" }.Contains(exp3tmpCall.Method.Name) && exp3tmpCall.Object != null)
775+
{
776+
//这段特别兼容 DbSet.Where 表达式解析 #216
777+
var exp3tmpTestCall = Expression.Call(exp3tmpCall.Object, exp3tmpCall.Method, exp3tmpCall.Arguments.Select(a =>
778+
{
779+
var a2 = a;
780+
if (a2.NodeType == ExpressionType.Quote) a2 = (a as UnaryExpression)?.Operand;
781+
if (a2?.NodeType == ExpressionType.Lambda)
782+
{
783+
var alambda = a2 as LambdaExpression;
784+
if (alambda.ReturnType == typeof(bool))
785+
return Expression.Constant(null, a.Type);// Expression.Lambda(Expression.Constant(true), alambda.Parameters);
786+
}
787+
return a;
788+
//if (a.Type == typeof(Expression<>).MakeGenericType(typeof(Func<,>).MakeGenericType(exp3tmp.Type.GetGenericArguments()[0], typeof(bool))))
789+
// return Expression.Lambda(Expression.Constant(true),
790+
}).ToArray());
791+
fsql = Expression.Lambda(exp3tmpTestCall).Compile().DynamicInvoke();
792+
var fsqlFindMethod = fsql.GetType().GetMethod(exp3tmpCall.Method.Name, exp3tmpCall.Arguments.Select(a => a.Type).ToArray());
793+
if (fsqlFindMethod == null)
794+
throw new Exception($"无法解析表达式方法 {exp3tmpCall.Method.Name}");
795+
var exp3StackOld = exp3Stack;
796+
exp3Stack = new Stack<Expression>();
797+
exp3Stack.Push(Expression.Call(Expression.Constant(fsql), fsqlFindMethod, exp3tmpCall.Arguments));
798+
while (exp3StackOld.Any()) exp3Stack.Push(exp3StackOld.Pop());
799+
}
774800
}
775801
if (fsql == null) fsql = Expression.Lambda(exp3tmp).Compile().DynamicInvoke();
776802
fsqlType = fsql?.GetType();

0 commit comments

Comments
 (0)