public IEnumerable <object> ToList <TReturn>(Expression <Func <TEntity, TReturn> > expression)
        {
            var code = expression.GetHashCode();

            if (SelectHandler == null)
            {
                SelectHandler = SqlHandler.Select <TEntity>();
            }
            var type = typeof(TReturn);

            if (!JoinExpressionMapping.Contains(code))
            {
                var           nclass = NClass.DefaultDomain().Public();
                StringBuilder script = new StringBuilder();
                // 获取构造函数参数
                var arguments = ((NewExpression)expression.Body).Arguments;
                //获取匿名类成员
                var members             = ((NewExpression)expression.Body).Members;
                var joinTypeFlagMapping = new Dictionary <Type, JoinTypeFlag>();
                for (int i = 0; i < arguments.Count; i++)
                {
                    // 方法类型参数
                    if (arguments[i].NodeType == ExpressionType.Call)
                    {
                        var methodExpression    = (MethodCallExpression)arguments[i];
                        var methodDeclaringType = methodExpression.Method.DeclaringType;
                        if (methodDeclaringType.IsGenericType && methodDeclaringType.GetGenericTypeDefinition().Name.Contains("Join"))
                        {
                            var joinType = methodDeclaringType.GetGenericArguments()[0];
                            if (methodExpression.Arguments[0].NodeType == ExpressionType.Quote)
                            {
                                var quoteExpression = (UnaryExpression)methodExpression.Arguments[0];
                                if (quoteExpression.Operand.NodeType == ExpressionType.Lambda)
                                {
                                    var lambdaExpression = (LambdaExpression)quoteExpression.Operand;
                                    if (lambdaExpression.Body.NodeType == ExpressionType.MemberAccess)
                                    {
                                        var memberExpression = (MemberExpression)lambdaExpression.Body;
                                        nclass.Property(item => item
                                                        .Public()
                                                        .Type(((PropertyInfo)memberExpression.Member).PropertyType)
                                                        .Name(memberExpression.Member.Name));

                                        var definitionType = methodDeclaringType.GetGenericTypeDefinition();
                                        if (definitionType == typeof(InnerJoin <>))
                                        {
                                            joinTypeFlagMapping[joinType] = JoinTypeFlag.Inner;
                                            script.Append(InnerJoin.GetJoinScript(joinType));
                                        }
                                        else if (definitionType == typeof(LeftJoin <>))
                                        {
                                            joinTypeFlagMapping[joinType] = JoinTypeFlag.Left;
                                            script.Append(LeftJoin.GetJoinScript(joinType));
                                        }
                                        else if (definitionType == typeof(RightJoin <>))
                                        {
                                            joinTypeFlagMapping[joinType] = JoinTypeFlag.Right;
                                            script.Append(RightJoin.GetJoinScript(joinType));
                                        }
                                        script.Append($".\"{memberExpression.Member.Name}\" AS \"{members[i].Name}\",");
                                    }
                                }
                            }
                        }
                    }
                    else if (arguments[i].NodeType == ExpressionType.MemberAccess)
                    {
                        var memberExpression = (MemberExpression)arguments[i];
                        nclass.Property(item => item
                                        .Public()
                                        .Type(((PropertyInfo)memberExpression.Member).PropertyType)
                                        .Name(memberExpression.Member.Name));
                        script.Append($"a.\"{memberExpression.Member.Name}\",");
                    }
                    //JoinObjectCache<ISelect<T>, TReturn>.GetObjects = NDelegate.RandomDomain().Func<ISelect<T>, object>(builder.ToString());
                }
                if (script.Length > 1)
                {
                    script.Length -= 1;
                    var joinScript = script.ToString();
                    JoinExpressionMapping = JoinExpressionMapping.Add(code);

                    var tempClass = nclass.GetType();
                    ProxyCaller <TEntity, TReturn> .Add(code, NDelegate
                                                        .DefaultDomain(item => item.LogSyntaxError())
                                                        .Func <ISelect <TEntity>, IEnumerable <object> >($"return arg.ToList<{tempClass.GetDevelopName()}>(\"{joinScript.Replace("\"","\\\"")}\");"));

                    var builder = new StringBuilder();
                    foreach (var item in joinTypeFlagMapping)
                    {
                        var    joinFieldCache = OrmNavigate <TEntity> .JoinScriptMapping[item.Key];
                        string joinAlias      = string.Empty;
                        switch (item.Value)
                        {
                        case JoinTypeFlag.Left:
                            joinAlias = LeftJoin.GetJoinScript(item.Key);
                            builder.Append($"obj.LeftJoin(\"");
                            break;

                        case JoinTypeFlag.Inner:
                            joinAlias = InnerJoin.GetJoinScript(item.Key);
                            builder.Append($"obj.InnerJoin(\"");
                            break;

                        case JoinTypeFlag.Right:
                            joinAlias = RightJoin.GetJoinScript(item.Key);
                            builder.Append($"obj.RightJoin(\"");
                            break;

                        default:
                            break;
                        }
                        var joinFieldScript = $"\"{item.Key.Name}\" AS {joinAlias} ON a.\"{joinFieldCache.src}\" = {joinAlias}.\"{joinFieldCache.dst}\"";
                        builder.Append(joinFieldScript.Replace("\"", "\\\""));
                        builder.AppendLine("\");");
                    }

                    //$"\"{typeof(TJoinEntity).Name}\" AS {InnerJoinHelper<TJoinEntity>.JoinAliasName} ON a.\"{srcFieldName}\" = {InnerJoinHelper<TJoinEntity>.JoinAliasName}.\"{destFieldName}\"")
                    JoinFiller <TEntity, TReturn> .Add(code, NDelegate
                                                       .DefaultDomain()
                                                       .Action <ISelect <TEntity> >(builder.ToString()));
                }
            }

            JoinFiller <TEntity, TReturn> .HandlerSelect(code, SelectHandler);

            return(ProxyCaller <TEntity, TReturn> .ToList(code, SelectHandler));
        }
Exemple #2
0
        static void Main(string[] args)
        {
            DomainManagement.RegisterDefault <AssemblyDomain>();
            //var @operator = FastMethodOperator.DefaultDomain();
            //var actionDelegate = @operator
            //    .Param(typeof(string), "parameter")
            //    .Body("Console.WriteLine(parameter);")
            //    .Compile();

            //actionDelegate.DynamicInvoke("HelloWorld!");
            //var action = (Action<string>)actionDelegate;
            //action("HelloWorld!");
            //actionDelegate.DisposeDomain();

            //起个类
            NClass nClass = NClass.DefaultDomain();

            nClass
            .Namespace("MyNamespace")
            .Public()
            .Name("MyClass")
            .Ctor(ctor => ctor.Public().Body("MyField=\"Hello\";"))
            .Property(prop => prop
                      .Type(typeof(string))
                      .Name("MyProperty")
                      .Public()
                      .OnlyGetter("return \"World!\";")
                      );


            //添加方法
            MethodBuilder mb = new MethodBuilder();

            mb
            .Public()
            .Override()
            .Name("ToString")
            .Body("return MyField+\" \"+MyProperty;")
            .Return(typeof(string));
            nClass.Method(mb);


            //添加字段
            FieldBuilder fb = nClass.GetFieldBuilder();

            fb.Public()
            .Name("MyField")
            .Type <string>();


            //动态调用动态创建的类
            var action = NDelegate
                         .RandomDomain()
                         .Action("Console.WriteLine((new MyClass()).ToString());", nClass.GetType());

            action();
            action.DisposeDomain();
            //Console.WriteLine(typeof(List<int>[]).GetRuntimeName());
            //Console.WriteLine(typeof(List<int>[,]).GetRuntimeName());
            //Console.WriteLine(typeof(int[,]).GetRuntimeName());
            //Console.WriteLine(typeof(int[][]).GetRuntimeName());
            //Console.WriteLine(typeof(int[][,,,]).GetRuntimeName());
            Console.ReadKey();
        }