public T GetValue <T>(int ordinal) { object value = reader.GetValue(ordinal); var toType = typeof(T); var fromType = value.GetType(); if (fromType == toType) { return((T)value); } if (value == DBNull.Value) { return(default(T)); } if (toType == ULinq.BinaryType) { return((T)ULinq.BinaryCtor(value as byte[])); } return((T)Converter.Convert(value, typeof(T))); }
public static void Init(Assembly asm) { var instance = new ULinq(); //var asm = linqToSqlClassType.Assembly; EntityRefType = asm.GetType(StrEntityRefType); EntitySetType = asm.GetType(StrEntitySetType); BinaryType = asm.GetType(StrBinaryType); BinaryCtor = BinaryType.GetConstructor(new Type[] { typeof(byte[]) }).GetCreator(); SqlType.TypeMap[BinaryType.TypeHandle.Value.GetHashCode()] = DBType.Binary; instance.Table = new TableAttribute(); instance.Table.Type = asm.GetType(ULinq.StrTableAttributeType); instance.Table.Name = instance.Table.Type.GetProperty("Name").GetGetter(); instance.Column = new ColumnAttribute(); instance.Column.Type = asm.GetType(ULinq.StrColumnAttributeType); instance.Column.Name = instance.Column.Type.GetProperty("Name").GetGetter(); instance.Column.CanBeNull = instance.Column.Type.GetProperty("CanBeNull").GetGetter(); instance.Column.IsDbGenerated = instance.Column.Type.GetProperty("IsDbGenerated").GetGetter(); instance.Column.IsPrimaryKey = instance.Column.Type.GetProperty("IsPrimaryKey").GetGetter(); instance.Column.IsVersion = instance.Column.Type.GetProperty("IsVersion").GetGetter(); instance.Column.AutoSync = instance.Column.Type.GetProperty("AutoSync").GetGetter(); instance.Column.DbType = instance.Column.Type.GetProperty("DbType").GetGetter(); instance.Column.Expression = instance.Column.Type.GetProperty("Expression").GetGetter(); instance.Column.IsDiscriminator = instance.Column.Type.GetProperty("IsDiscriminator").GetGetter(); instance.Column.Storage = instance.Column.Type.GetProperty("Storage").GetGetter(); instance.Column.UpdateCheck = instance.Column.Type.GetProperty("UpdateCheck").GetGetter(); instance.Association = new AssociationAttribute(); instance.Association.Type = asm.GetType(ULinq.StrAssociationAttributeType); instance.Association.ThisKey = instance.Association.Type.GetProperty("ThisKey").GetGetter(); instance.Association.OtherKey = instance.Association.Type.GetProperty("OtherKey").GetGetter(); instance.Association.IsForeignKey = instance.Association.Type.GetProperty("IsForeignKey").GetGetter(); var sqlMethodsType = asm.GetType(ULinq.StrSqlMethhodsType); //var flags = BindingFlags.Public | BindingFlags.Static; var dateDiffDay = sqlMethodsType.GetMethod("DateDiffDay", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffDay] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Day, startTime, endTime)); var dateDiffHour = sqlMethodsType.GetMethod("DateDiffHour", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffHour] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Hour, startTime, endTime)); var dateDiffMicrosecond = sqlMethodsType.GetMethod("DateDiffMicrosecond", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffMicrosecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Microsecond, startTime, endTime)); var dateDiffMillisecond = sqlMethodsType.GetMethod("DateDiffMillisecond", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffMillisecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Millisecond, startTime, endTime)); var dateDiffMinute = sqlMethodsType.GetMethod("DateDiffMinute", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffMinute] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Minute, startTime, endTime)); var dateDiffMonth = sqlMethodsType.GetMethod("DateDiffMonth", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffMonth] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Month, startTime, endTime)); var dateDiffNanosecond = sqlMethodsType.GetMethod("DateDiffNanosecond", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffNanosecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Nanosecond, startTime, endTime)); var dateDiffSecond = sqlMethodsType.GetMethod("DateDiffSecond", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffSecond] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Second, startTime, endTime)); var dateDiffYear = sqlMethodsType.GetMethod("DateDiffYear", new Type[] { typeof(DateTime), typeof(DateTime) }); MethodMapping.Mappings[dateDiffYear] = MethodMapping.Lambda <DateTime, DateTime, int>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Year, startTime, endTime)); // var dateDiffDayForNullable = sqlMethodsType.GetMethod("DateDiffDay", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffDayForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Day, startTime, endTime)); var dateDiffHourForNullable = sqlMethodsType.GetMethod("DateDiffHour", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffHourForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Hour, startTime, endTime)); var dateDiffMicrosecondForNullable = sqlMethodsType.GetMethod("DateDiffMicrosecond", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffMicrosecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Microsecond, startTime, endTime)); var dateDiffMillisecondForNullable = sqlMethodsType.GetMethod("DateDiffMillisecond", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffMillisecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Millisecond, startTime, endTime)); var dateDiffMinuteForNullable = sqlMethodsType.GetMethod("DateDiffMinute", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffMinuteForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Minute, startTime, endTime)); var dateDiffMonthForNullable = sqlMethodsType.GetMethod("DateDiffMonth", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffMonthForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Month, startTime, endTime)); var dateDiffNanosecondForNullable = sqlMethodsType.GetMethod("DateDiffNanosecond", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffNanosecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Nanosecond, startTime, endTime)); var dateDiffSecondForNullable = sqlMethodsType.GetMethod("DateDiffSecond", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffSecondForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Second, startTime, endTime)); var dateDiffYearForNullable = sqlMethodsType.GetMethod("DateDiffYear", new Type[] { typeof(DateTime?), typeof(DateTime?) }); MethodMapping.Mappings[dateDiffYearForNullable] = MethodMapping.Lambda <DateTime?, DateTime?, int?>((startTime, endTime) => SqlFunctions.DateDiff(DateParts.Year, startTime, endTime)); Instance = instance; }
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(); }
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); }