From 491f163e5dea3cc1ccc9f7bbd7a4d4d4b4a4a66f Mon Sep 17 00:00:00 2001 From: mk3008 Date: Sun, 5 Nov 2023 10:52:50 +0900 Subject: [PATCH] #253 refactoring FromTableInfoParser --- .../Analysis/FromTableInfoParser.cs | 89 ++++++++++--------- .../Analysis/JoinTableInfoParserTest.cs | 21 ++++- 2 files changed, 68 insertions(+), 42 deletions(-) diff --git a/src/QueryBuilderByLinq/Analysis/FromTableInfoParser.cs b/src/QueryBuilderByLinq/Analysis/FromTableInfoParser.cs index 46db9c7c..46fad534 100644 --- a/src/QueryBuilderByLinq/Analysis/FromTableInfoParser.cs +++ b/src/QueryBuilderByLinq/Analysis/FromTableInfoParser.cs @@ -35,8 +35,8 @@ public static class FromTableInfoParser var method = (MethodCallExpression)exp; if (method.Arguments.Count != 2) return null; - var queryExpression = method.GetArgument(0); - if (queryExpression == null) return null; + var ce = method.GetArgument(0); + if (ce == null) return null; var operand = method.GetArgument(1).GetOperand(); if (operand == null) return null; @@ -45,23 +45,12 @@ public static class FromTableInfoParser var parameter = operand.Parameters[0]; if (parameter.Type == typeof(DualTable)) return null; - if (queryExpression.Value is IQueryable q && q.Provider is TableQuery provider) + if (TryParse(ce, parameter, out var f)) { - // root syntax - if (provider.InnerQuery != null) - { - return new FromTableInfo(provider.InnerQuery.ToQueryAsPostgres(), parameter.Name!); - } - else - { - return new FromTableInfo(provider.TableName, parameter.Name!); - } - } - else - { - // nest sytax - return new FromTableInfo(parameter.ToTypeTable(), parameter.Name!); + return f; } + // nest sytax + return new FromTableInfo(parameter.ToTypeTable(), parameter.Name!); } /// @@ -77,42 +66,60 @@ public static class FromTableInfoParser var method = (MethodCallExpression)exp; if (method.Arguments.Count != 3) return null; - //query - var lambda = method.GetArgument(1).GetOperand(); - if (lambda == null) return null; - - var body = lambda.GetBody(); + var ce = method.GetArgument(0); + var body = method.GetArgument(1).GetOperand().GetBody(); ; if (body == null) return null; - // no relation pattern. - var operand = method.GetArgument(2).GetOperand(); - if (operand == null) return null; - if (operand.Parameters.Count != 2) return null; - var parameter = operand.Parameters[1]; - if (body.Method.Name == nameof(Sql.FromTable)) { + // no relation pattern. + var operand = method.GetArgument(2).GetOperand(); + if (operand == null) return null; + if (operand.Parameters.Count != 2) return null; + + var parameter = operand.Parameters[1]; return ParseCore3ArgumentsFromTable(body, parameter); } - else if (body.Method.Name == nameof(Sql.InnerJoinTable) || body.Method.Name == nameof(Sql.LeftJoinTable) || body.Method.Name == nameof(Sql.CrossJoinTable)) + else if (ce != null && (body.Method.Name == nameof(Sql.InnerJoinTable) || body.Method.Name == nameof(Sql.LeftJoinTable) || body.Method.Name == nameof(Sql.CrossJoinTable))) { - /* - has relation pattern. - 'body' is relation conditions. - 'parameter' is relation alias. - */ - - //query - lambda = method.GetArgument(2).GetOperand(); - if (lambda == null || lambda.Parameters.Count != 2) return null; - - var prm = lambda.Parameters[0]; - return new FromTableInfo(prm.ToTypeTable(), prm.Name!); + // has relation pattern. + var operand = method.GetArgument(2).GetOperand(); + if (operand == null || operand.Parameters.Count != 2) return null; + + var parameter = operand.Parameters[0]; + + if (TryParse(ce, parameter, out var f)) + { + return f; + } + return new FromTableInfo(parameter.ToTypeTable(), parameter.Name!); } return null; } + private static bool TryParse(ConstantExpression methodBody, ParameterExpression parameter, out FromTableInfo from) + { + from = null!; + + if (methodBody.Value is IQueryable q && q.Provider is TableQuery provider) + { + if (provider.InnerQuery != null) + { + // subquery pattern. + from = new FromTableInfo(provider.InnerQuery.ToQueryAsPostgres(), parameter.Name!); + return true; + } + else + { + // override table name pattern. + from = new FromTableInfo(provider.TableName, parameter.Name!); + return true; + } + } + return false; + } + private static FromTableInfo? ParseCore3ArgumentsFromTable(MethodCallExpression body, ParameterExpression parameter) { if (body.Method.Name != nameof(Sql.FromTable)) throw new InvalidProgramException(); diff --git a/test/QueryBuilderByLinq.Test/Analysis/JoinTableInfoParserTest.cs b/test/QueryBuilderByLinq.Test/Analysis/JoinTableInfoParserTest.cs index 6b9d9772..6abc973a 100644 --- a/test/QueryBuilderByLinq.Test/Analysis/JoinTableInfoParserTest.cs +++ b/test/QueryBuilderByLinq.Test/Analysis/JoinTableInfoParserTest.cs @@ -31,7 +31,7 @@ public void NoRelationTest() } [Fact] - public void InnerJoinTest() + public void InnerJoinTypeTableTest() { var query = from s in FromTable() from a in InnerJoinTable
(x => s.article_id == x.article_id) @@ -48,6 +48,25 @@ from a in InnerJoinTable
(x => s.article_id == x.article_id) Assert.Empty(joins); } + [Fact] + public void InnerJoinStringTableTest() + { + var query = from s in FromTable("sales") + from a in InnerJoinTable
("articles", x => s.article_id == x.article_id) + select a; + + Monitor.Log(query); + + var from = FromTableInfoParser.Parse(query.Expression); + Assert.Equal("s", from?.Alias); + Assert.Equal("sales AS s", from?.ToSelectable().ToText()); + + + var joins = JoinTableInfoParser.Parse(query.Expression); + + Assert.Empty(joins); + } + [Fact] public void LeftJoinTest() {