// The only purpose of this method is to give the client more accurate information about the target property // which caused the InvalidCastException exception. This method may even fail with inner exception and/or return null, // and in that case the less accurate InvalidCastException info will be shown to the client. internal static Row <string, string, string> AnalyseInvalidCastException(Connectable connectable, Type type, int tableIndex) { try { using (SqlConnection cn = new SqlConnection(connectable.ConnectionString)) { cn.Open(); Importer.ExecuteBulkInsert(connectable, cn); using (SqlCommand cmd = new SqlCommand(connectable.Sql, cn)) { cmd.CommandTimeout = connectable.CommandTimeout; int i = 0; using (SqlDataReader reader = cmd.ExecuteReader()) { while (i++ != tableIndex) { if (!reader.NextResult()) { return(null); } } DataTable schema = reader.GetSchemaTable(); int hash = GetLoaderHash(reader); var cacheKey = Cache.CreateLoaderCacheKey(hash, type); Cache.LoaderCacheValue cacheValue; if (!Cache.Loaders.TryGetValue(cacheKey, out cacheValue)) { return(null); // do not continue with analysis if cache does not exist (not likely) } int j = 0; foreach (var column in cacheValue.Columns) { DataRow row; if (Row.IsRow(type)) { row = schema.Rows[j++]; } else { row = schema.AsEnumerable() .Where(a => a.Field <string>(_columnNameText).EqualsCS(column.ColumnName)) .Select(a => a) .FirstOrDefault(); } if (row != null) { string sqlTypeName = row.Field <string>(_dataTypeNameText); var clrInfo = Mapping.ClrMapping[column.ValueType]; bool ismatch = false; foreach (var dbtype in clrInfo.DTypes) { if (Mapping.SqlMapping[dbtype].SqlPlain.EqualsCS(sqlTypeName, false)) { ismatch = true; break; } } if (!ismatch) { return(Row.Create(column.ColumnName, column.ValueType.ToString(), sqlTypeName)); } } } } } } } // safe: the "real" exception has already been caught catch { } return(null); }
private static void _LoadTableSetBody( Connectable connectable, Func <IDataReader, TableSetLoaderArgs> tableSetLoader, Type currentTableType, out int returnValue) { int tableIndex = 0; try { using (SqlConnection cn = new SqlConnection(connectable.ConnectionString)) { cn.Open(); Importer.ExecuteBulkInsert(connectable, cn); using (SqlCommand cmd = new SqlCommand(connectable.Sql, cn)) { cmd.CommandTimeout = connectable.CommandTimeout; SqlDataReader reader = cmd.ExecuteReader(); try { var loaderException = tableSetLoader(reader); if (loaderException != null) { currentTableType = loaderException.TableType; tableIndex = loaderException.TableIndex; throw loaderException.Exception; } returnValue = Reader.ReadOutputData(reader, connectable); } finally { reader.Close(); } } } } catch (QueryTalkException ex) { ex.ObjectName = ((IName)connectable.Executable).Name; ex.Method = Text.Method.Go; throw; } catch (System.InvalidCastException) // "Specified cast is not valid." { var mismatchData = Loader.AnalyseInvalidCastException(connectable, currentTableType, tableIndex); // throw exception with more accurate report if (mismatchData != null) { throw Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.Go, currentTableType, mismatchData, tableIndex); } // throw exception with less accurate report (not likely to happen) else { throw Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.Go, currentTableType, new Row <string, string, string>(), tableIndex); } } }
/// <summary> /// Executes a bulk insert. /// </summary> /// <param name="data">The data to be inserted.</param> /// <param name="table">Is a target table where the data is inserted.</param> public void BulkInsertGo(Result <DataTable> data, TableArgument table) { PublicInvoker.Call(Assembly.GetCallingAssembly(), (ca) => Importer.ExecuteBulkInsert(ca, data.ToDataTable(), table, this)); }
/// <summary> /// Executes a bulk insert. /// </summary> /// <param name="rows">The data to be inserted.</param> public void BulkInsertGo <T>(IEnumerable <T> rows) where T : DbRow { PublicInvoker.Call(Assembly.GetCallingAssembly(), (ca) => Importer.ExecuteBulkInsert(ca, rows, this)); }
internal static Result <T> LoadTable <T>(Connectable connectable, Action <T> rowHandler, bool allowEmpty = false) { IEnumerable <T> table = null; int returnValue = 0; Type type = typeof(T); if (type == typeof(DataTable)) { throw new QueryTalkException("Reader.LoadTable<T>", QueryTalkExceptionType.DataTableCannotEnumerate, ((IName)connectable.Executable).Name, ".Go<DataTable>", null); } try { using (SqlConnection cn = new SqlConnection(connectable.ConnectionString)) { cn.Open(); Importer.ExecuteBulkInsert(connectable, cn); using (SqlCommand cmd = new SqlCommand(connectable.Sql, cn)) { cmd.CommandTimeout = connectable.CommandTimeout; SqlDataReader reader = cmd.ExecuteReader(); try { table = _load <T>(connectable, reader, rowHandler, allowEmpty); returnValue = Reader.ReadOutputData(reader, connectable); } finally { reader.Close(); } } } } catch (QueryTalkException ex) { ex.ObjectName = ((IName)connectable.Executable).Name; ex.Method = Text.Method.Go; throw; } catch (System.InvalidCastException) // "Specified cast is not valid." { var mismatchData = Loader.AnalyseInvalidCastException(connectable, type, 0); // throw exception with accurate report if (mismatchData != null) { var exception = Reader.TypeMismatchException(((IName)connectable.Executable).Name, Text.Method.Go, type, mismatchData); throw exception; } // throw exception with less accurate report (not likely to happen) else { var exception = Reader.TypeMismatchException( ((IName)connectable.Executable).Name, Text.Method.Go, type, new Row <string, string, string>()); throw exception; } } catch (System.ArgumentNullException ex) { var exception = ClrException(ex, "Load", connectable, Text.Method.Go, String.Format("data class = {0}", typeof(T))); exception.Extra = Text.Free.DataClassNoConstructorExtra; throw exception; } var result = new Result <T>(connectable, table); result.ReturnValue = returnValue; return(result); }