static DbConfiguration()
        {
            ManualResetEvent mre = new ManualResetEvent(false);

            ThreadPool.QueueUserWorkItem(s =>
            {
                var dlinqAsm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(p => p.GetName().Name == "System.Data.Linq");
                if (dlinqAsm != null)
                {
                    ULinq.Init(dlinqAsm);
                }
                var dataAnnotiationAsm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(p => p.GetName().Name == DataAnnotationMappingAdapter.StrAssemblyName);
                if (dataAnnotiationAsm != null)
                {
                    DataAnnotationMappingAdapter.Init(dataAnnotiationAsm);
                }
                var efDataAnnotiationAsm = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(p => p.GetName().Name == EFDataAnnotiationAdapter.StrAssemblyName);
                if (efDataAnnotiationAsm != null)
                {
                    EFDataAnnotiationAdapter.Init(efDataAnnotiationAsm);
                }
                //初始化PrimitiveMapper
                Converter.IsPrimitiveType(Types.Boolean);
                //初始化Expressor
                var len      = MethodRepository.Len;
                var mappings = UWay.Skynet.Cloud.Data.Common.MethodMapping.Mappings;

                mre.Set();
            }
                                         );

            Options = new Dictionary <string, DbConfigurationInfo>(StringComparer.Ordinal);
            items   = new Dictionary <string, DbConfiguration>(StringComparer.Ordinal);


            Options["MySql.Data.MySqlClient"] = new DbConfigurationInfo
            {
                Driver              = new MySqlDriver(),
                Dialect             = new MySqlDialect(),
                FuncRegistry        = new UWay.Skynet.Cloud.Data.Dialect.Function.MySQL.MySqlFunctionRegistry(),
                DbExpressionBuilder = new MySqlExpressionBuilder(),
                SqlBuilder          = (dialect, funcRegistry) => new MySqlBuilder {
                    Dialect = dialect, FuncRegistry = funcRegistry
                },

                ScriptGenerator = () => new MySQLScriptGenerator(),
                ScriptExecutor  = () => new MySQLScriptExecutor(),
                SchemaLoader    = () => new MySqlSchemaLoader(),
            };

            Options["Oracle.ManagedDataAccess.Client"] = new DbConfigurationInfo
            {
                Driver              = new OracleODPDriver(),
                Dialect             = new OracleDialect(),
                FuncRegistry        = new UWay.Skynet.Cloud.Data.Dialect.Function.Oracle.OracleFunctionRegistry(),
                DbExpressionBuilder = new OracleExpressionBuilder(),
                SqlBuilder          = (dialect, funcRegistry) => new OracleSqlBuilder {
                    Dialect = dialect, FuncRegistry = funcRegistry
                },

                ScriptGenerator = () => new OracleScriptGenerator(),
                ScriptExecutor  = () => new OracleScriptExecutor(),
                SchemaLoader    = () => new OracleSchemaLoader(),
            };

            Options[DbProviderNames.SqlServer] = new DbConfigurationInfo
            {
                Driver              = new SqlServer2005Driver(),
                Dialect             = new MsSql2005Dialect(),
                FuncRegistry        = new UWay.Skynet.Cloud.Data.Dialect.Function.MsSql.MsSql2005FunctionRegistry(),
                DbExpressionBuilder = new MsSql2005ExpressionBuilder(),
                SqlBuilder          = (dialect, funcRegistry) => new SqlServer2005SqlBuilder {
                    Dialect = dialect, FuncRegistry = funcRegistry
                },

                ScriptGenerator = () => new SqlServerScriptGenerator(),
                ScriptExecutor  = () => new SqlServerScriptExecutor(),
                SchemaLoader    = () => new SqlServerSchemaLoader(),
            };

            //Options["System.Data.SQLite"] = new DbConfigurationInfo
            //{
            //    Driver = new SQLiteDriver(),
            //    Dialect = new SQLiteDialect(),
            //    FuncRegistry = new UWay.Skynet.Cloud.Data.Dialect.Function.SQLite.SQLiteFunctionManager(),
            //    DbExpressionBuilder = new SQLiteExpressionBuilder(),
            //    SqlBuilder = (dialect, funcRegistry) => new SQLiteSqlBuilder { Dialect = dialect, FuncRegistry = funcRegistry },

            //    ScriptGenerator = () => new SQLiteScriptGenerator(),
            //    ScriptExecutor = () => new SQLiteScriptExecutor(),
            //    SchemaLoader = () => new SQLiteSchemaLoader(),

            //};

            //Options["System.Data.SqlServerCe.3.5"] = new DbConfigurationInfo
            //{
            //    Driver = new SqlCeDriver(),
            //    Dialect = new SqlCe35Dialect(),
            //    FuncRegistry = new UWay.Skynet.Cloud.Data.Dialect.Function.SqlCe.SqlCeFunctionRegistry(),
            //    DbExpressionBuilder = new SqlCe35ExpressionBuilder(),
            //    SqlBuilder = (dialect, funcRegistry) => new SqlCeBuilder { Dialect = dialect, FuncRegistry = funcRegistry },

            //    ScriptGenerator = () => new SqlCeScriptGenerator(),
            //    ScriptExecutor = () => new SqlCeScriptExecutor(),
            //    SchemaLoader = () => new SqlCeSchemaLoader(),

            //};

            //Options["System.Data.SqlServerCe.4.0"] = new DbConfigurationInfo
            //{
            //    Driver = new SqlCeDriver(),
            //    Dialect = new SqlCe35Dialect(),
            //    FuncRegistry = new UWay.Skynet.Cloud.Data.Dialect.Function.SqlCe.SqlCeFunctionRegistry(),
            //    DbExpressionBuilder = new SqlCe35ExpressionBuilder(),
            //    SqlBuilder = (dialect, funcRegistry) => new SqlCeBuilder { Dialect = dialect, FuncRegistry = funcRegistry },

            //    ScriptGenerator = () => new SqlCeScriptGenerator(),
            //    ScriptExecutor = () => new SqlCeScriptExecutor(),
            //    SchemaLoader = () => new SqlCeSchemaLoader(),

            //};

            //providerNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
            //foreach (var item in DbProviderFactories.GetFactoryClasses().Rows.Cast<DataRow>().Select(p => p["InvariantName"] as string))
            //    providerNames.Add(item);

            mre.WaitOne();
            mre.Close();
        }
Exemplo n.º 2
0
        protected override Expression VisitMethodCall(MethodCallExpression m)
        {
            m = base.VisitMethodCall(m) as MethodCallExpression;

            var lambda = MethodMapping.ConvertMember(m.Method);

            if (lambda != null)
            {
                var ef    = lambda.Body.Unwrap();
                var parms = new Dictionary <string, ParameterMapping>(lambda.Parameters.Count);
                var pn    = m.Method.IsStatic ? 0 : -1;

                foreach (var p in lambda.Parameters)
                {
                    parms.Add(p.Name, new ParameterMapping(pn++, p.Type));
                }

                var pie = ef.Convert(wpi =>
                {
                    if (wpi.NodeType == ExpressionType.Parameter)
                    {
                        ParameterMapping n;
                        if (parms.TryGetValue(((ParameterExpression)wpi).Name, out n))
                        {
                            var tmp = n.Index < 0 ? m.Object : m.Arguments[n.Index];
                            if (tmp.Type != n.Type)
                            {
                                return(Expression.Convert(tmp, n.Type));
                            }
                            return(tmp);
                        }
                    }

                    return(wpi);
                });

                if (m.Method.ReturnType != pie.Type)
                {
                    pie = Expression.Convert(pie, m.Method.ReturnType);
                }

                return(Visit(pie));
            }



            var methodName    = m.Method.Name;
            var declaringType = m.Method.DeclaringType;

            if (declaringType == typeof(System.Convert))
            {
                Expression operand = null;
                Type       toType  = null;
                if (m.Method.Name.StartsWith("To"))
                {
                    toType  = ClassLoader.Load("System." + m.Method.Name.Replace("To", ""));
                    operand = m.Arguments[0];
                }

                if (operand != null && toType != null && toType != Types.Object)
                {
                    return(Expression.Call(MethodRepository.GetConvertMethod(operand.Type, toType), operand));
                }
            }

            if (typeof(TypeConverter).IsAssignableFrom(declaringType))
            {
                Expression operand = null;
                Type       toType  = null;

                if (methodName.StartsWith("ConvertFrom"))
                {
                    var  c             = m.Object as ConstantExpression;
                    Type converterType = null;
                    if (c != null)
                    {
                        converterType = (m.Object as ConstantExpression).Value.GetType();
                    }
                    else
                    {
                        var ma = m.Object as MemberExpression;
                        if (ma != null)
                        {
                            c = ma.Expression as ConstantExpression;
                            if (c == null)
                            {
                                throw new NotSupportedException(string.Format("The method '{0}' is not supported", m.Method.Name));
                            }

                            converterType = ma.Member.GetGetter()(c.Value).GetType();
                        }
                    }
                    toType = ClassLoader.Load("System." + converterType.Name.Replace("Converter", ""));
                    if (toType == null)
                    {
                        throw new NotSupportedException(string.Format("The method '{0}' is not supported", m.Method.Name));
                    }

                    if (methodName == "ConvertFrom" && m.Arguments.Count == 1)
                    {
                        operand = m.Arguments[0];
                    }
                    else if (methodName == "ConvertFromString" && m.Arguments.Count == 1)
                    {
                        operand = m.Arguments[0];
                    }
                    else if (methodName == "ConvertFromInvariantString" && m.Arguments.Count == 1)
                    {
                        operand = m.Arguments[0];
                    }
                }
                else if (methodName == "ConvertTo" && m.Arguments.Count == 2)
                {
                    operand = m.Arguments[0];
                    toType  = (m.Arguments[1] as ConstantExpression).Value as Type;
                }
                else if (methodName == "ConvertToInvariantString" && m.Arguments.Count == 1)
                {
                    operand = m.Arguments[0];
                    toType  = Types.String;
                }
                else if (methodName == "ConvertToString" && m.Arguments.Count == 1)
                {
                    operand = m.Arguments[0];
                    toType  = Types.String;
                }

                if (operand != null && toType != null && toType != Types.Object)
                {
                    return(Expression.Call(MethodRepository.GetConvertMethod(operand.Type, toType), operand));
                }
                throw new NotSupportedException(string.Format("The method '{0}' is not supported", methodName));
            }

            if (methodName == "Parse" &&
                m.Method.IsStatic &&
                (declaringType.IsValueType || declaringType.IsNullable()) &&
                m.Arguments.Count == 1 &&
                m.Method.ReturnType == m.Type)
            {
                Expression operand = m.Arguments[0];
                Type       toType  = declaringType.IsNullable() ? Nullable.GetUnderlyingType(declaringType) : declaringType;
                return(Expression.Call(MethodRepository.GetConvertMethod(operand.Type, toType), operand));
            }
            if (declaringType == Types.String)
            {
                if (methodName == "Concat")
                {
                    return(BindConcat(m.Arguments.ToArray()));
                }
                if (methodName == "Join")
                {
                    return(BindJoin(m));
                }
            }

            if (methodName == "ContainsValue" && IsSameOrParent(typeof(IDictionary <,>), declaringType))
            {
                var args = GetGenericArguments(declaringType, typeof(IDictionary <,>));
                var minf = EnumerableMethods
                           .First(s => s.Name == "Contains" && s.GetParameters().Length == 2)
                           .MakeGenericMethod(args[1]);

                return(Expression.Call(
                           minf,
                           Expression.PropertyOrField(m.Object, "Values"),
                           m.Arguments[0]));
            }
            if (methodName == "ContainsKey" && IsSameOrParent(typeof(IDictionary <,>), declaringType))
            {
                var args = GetGenericArguments(declaringType, typeof(IDictionary <,>));
                var minf = EnumerableMethods
                           .First(s => s.Name == "Contains" && s.GetParameters().Length == 2)
                           .MakeGenericMethod(args[1]);

                return(Expression.Call(
                           minf,
                           Expression.PropertyOrField(m.Object, "Keys"),
                           m.Arguments[0]));
            }


            if (declaringType.FullName == ULinq.StrSqlMethhodsType && declaringType.Assembly.GetName().Name == ULinq.StrAssemblyName)
            {
                ULinq.Init(declaringType.Assembly);
                return(Visit(m));
            }
            //if (methodName == "Like" && declaringType == typeof(SqlFunctions) && m.Arguments.Count == 5)
            //{
            //    return BindLike(
            //        m.Arguments[0]
            //        , m.Arguments[1]
            //        , (bool)(m.Arguments[2] as ConstantExpression).Value
            //        , (bool)(m.Arguments[3] as ConstantExpression).Value
            //        , (bool)(m.Arguments[4] as ConstantExpression).Value);
            //}

            if (typeof(Queryable).IsAssignableFrom(declaringType) || typeof(Enumerable).IsAssignableFrom(declaringType))
            {
                var elementType = UWay.Skynet.Cloud.Data.Linq.Internal.ReflectionHelper.GetElementType(m.Arguments[0].Type);
                switch (methodName)
                {
                case "Contains":
                    EntityMapping mapping;
                    if (DbContext.dbConfiguration.mappings.TryGetValue(elementType.TypeHandle.Value, out mapping))
                    {
                        // Expression left =
                    }
                    break;
                    //case "Aggregate":
                    //    {
                    //        var type = UWay.Skynet.Cloud.Reflection.TypeHelper.GetElementType(m.Arguments[0].Type);
                    //        if (type.IsNullable())
                    //            type = Nullable.GetUnderlyingType(type);
                    //        if (type.IsClass && type != Types.String)
                    //            throw new NotSupportedException("Not support 'Aggregate' function for complex type.");
                    //        break;
                    //    }
                    //case "ElementAt":
                    //    var index = m.Arguments[1];
                    //    var elementType = UWay.Skynet.Cloud.Reflection.TypeHelper.GetElementType(m.Arguments[0].Type);
                    //    var c = index as ConstantExpression;
                    //    if (c != null)
                    //    {
                    //        if((int)c.Value == 0)
                    //            return Expression.Call(typeof(Enumerable), "Take", new Type[] { elementType }, m.Arguments[0], Expression.Constant(1, Types.Int32));
                    //        index = Expression.Constant((int)c.Value + 1, Types.Int32);
                    //    }
                    //    else
                    //        index = Expression.Add(index, Expression.Constant(1, Types.Int32));
                    //    var s = Expression.Call(typeof(Enumerable), "Skip", new Type[] { elementType },m.Arguments[0], index);
                    //    return Expression.Call(typeof(Enumerable), "Take", new Type[] { elementType },s, Expression.Constant(1,Types.Int32));
                }
            }

            if (IsSameOrParent(typeof(IEnumerable <>), declaringType) &&
                !declaringType.IsArray &&
                m.Object != null &&
                m.Object.NodeType == ExpressionType.Constant &&
                !typeof(IQueryable).IsAssignableFrom(declaringType))
            {
                switch (methodName)
                {
                case "Contains":
                    var elementType = UWay.Skynet.Cloud.Data.Linq.Internal.ReflectionHelper.GetElementType(declaringType);
                    if (!DbContext.dbConfiguration.HasClass(elementType) && elementType != Types.Char)
                    {
                        var lst = (m.Object as ConstantExpression).Value as IEnumerable;
                        if (lst != null)
                        {
                            var items = lst.Cast <object>().ToArray();
                            var arry  = Array.CreateInstance(elementType, items.Length);
                            for (int i = 0; i < items.Length; i++)
                            {
                                arry.SetValue(items[i], i);
                            }
                            Expression array = Expression.Constant(arry);

                            var containsMethod = EnumerableMethods
                                                 .First(s => s.Name == "Contains" && s.GetParameters().Length == 2)
                                                 .MakeGenericMethod(elementType);
                            m = Expression.Call(containsMethod, array, m.Arguments[0]);
                        }
                    }
                    break;
                }
            }
            return(m);
        }