Inheritance: AstNode
Ejemplo n.º 1
0
        private CodeMemberMethod CreateFetch(AliasBase aliasBase, out CodeTypeReference anonType)
        {
            var statementDomArg = VisitChild(aliasBase.Statement);
            if (Scope.Current.IsTableRegistered(statementDomArg.Scope.CodeDomReference.TypeArguments[0].BaseType))
            {
                var scope = Scope.Current.GetTableDescriptor(statementDomArg.Scope.CodeDomReference.TypeArguments[0].BaseType);
                if (aliasBase.Alias == null)
                    aliasBase.Children.Add(new TableAlias { Id = statementDomArg.Scope.CodeDomReference.TypeArguments[0].BaseType });

                Scope.Current.Register(aliasBase.Alias.Id, new ScopeData<TableDescriptor> { Type = scope.Type, CodeDomReference = scope.CodeDomReference.TypeArguments[0] });
            }

            CodeMemberMethod method = new CodeMemberMethod();
            method.Name = "Fetch_" + Guid.NewGuid().ToString("N");
            _mainType.Type.Members.Add(method);

            var anon = "anon_" + Guid.NewGuid().ToString("N");
            var bufferTable = new CodeTypeDeclaration(anon) { TypeAttributes = TypeAttributes.NestedPrivate };
            bufferTable.BaseTypes.Add(new CodeTypeReference("IRow"));
            _mainType.Type.Members.Add(bufferTable);

            var field = new CodeMemberField();
            field.Name = aliasBase.Alias == null ? string.Empty : aliasBase.Alias.Id;
            field.Attributes = MemberAttributes.Public | MemberAttributes.Final;
            field.Type = statementDomArg.Scope.CodeDomReference.TypeArguments[0];
            _joinMembers.Add(field);
            bufferTable.Members.Add(field);

            method.Statements.Add(new CodeVariableDeclarationStatement(statementDomArg.Scope.CodeDomReference, "table", statementDomArg.CodeExpression));

            anonType = new CodeTypeReference(anon);

            var copyStatments = new CodeStatementCollection();
            copyStatments.Add(new CodeVariableDeclarationStatement(anonType, "t",
               new CodeObjectCreateExpression(anonType)));

            copyStatments.Add(new CodeAssignStatement(new CodePropertyReferenceExpression(new CodeVariableReferenceExpression("t"), field.Name),
                new CodeVariableReferenceExpression("o")));

            copyStatments.Add(new CodeMethodReturnStatement(new CodeVariableReferenceExpression("t")));

            var codeParams = new CodeParameterDeclarationExpressionCollection();
            codeParams.Add(new CodeParameterDeclarationExpression(statementDomArg.Scope.CodeDomReference.TypeArguments[0], "o"));
            var copyMethod = CreateCopyMethod(codeParams, copyStatments);

            var anonExpression = new CodeSnippetExpression("o => {" + GenerateCodeFromStatement(
                new CodeMethodReturnStatement(
                    new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(null, copyMethod.Name),
                        new CodeVariableReferenceExpression("o")))) + "}");

            method.Statements.Add(new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(
                       new CodeTypeReferenceExpression("table"), "Select"), anonExpression)));

            method.ReturnType = new CodeTypeReference("IEnumerable", anonType);
            copyMethod.ReturnType = anonType;

            return method;
        }
        private string ReplaceBooleanStatement(AliasBase aliasBAse, string statement)
        {
            //the inner is the new join (ic). Everything else is outer (oc)

            string innerMatch = @"row\.(" + aliasBAse.Alias.Id + @")\.(\w+)";
            string outerMatch = @"row\.([^" + aliasBAse.Alias.Id + @"])\.(\w+)";
            statement = Regex.Replace(statement, innerMatch, "ic.$1.$2");
            statement = Regex.Replace(statement, outerMatch, "oc.$1.$2");

            return statement;
        }