private List <ColumnInfo> GetTableSchema(string tableName) { return(NpgsqlHelper.GetColumnsInfo(context, tableName)); }
public static List <T> BulkSelect <T, TKey>( this IQueryable <T> source, Expression <Func <T, TKey> > keyExpression, IEnumerable <TKey> keyData) { EnsureNoNavigationProperties(keyExpression); BulkSelectInterceptor.StartInterception(); var keyDataTable = $"_schema_{DateTime.Now.Ticks}"; var schemaQuery = source.Select(keyExpression); var schemaSql = $"CREATE TEMP TABLE {keyDataTable} ON COMMIT DROP AS ({schemaQuery} LIMIT 0)"; var context = NpgsqlHelper.GetContextFromQuery(source); var conn = NpgsqlHelper.GetNpgsqlConnection(context); var localTr = NpgsqlHelper.EnsureOrStartTransaction(context); try { context.Database.ExecuteSqlCommand(schemaSql); var columnsInfo = NpgsqlHelper.GetColumnsInfo(context, keyDataTable); var propsMap = GetPropertiesMap( ((IObjectContextAdapter)context).ObjectContext, schemaQuery.Expression, typeof(TKey)); var mapsInfo = new List <MappingInfo>(); foreach (var propMap in propsMap) { var cinfo = columnsInfo[propMap.Item2]; mapsInfo.Add(new MappingInfo() { Property = propMap.Item1, ColumnInfo = cinfo, NpgsqlType = NpgsqlBulkUploader.GetNpgsqlType(cinfo) }); } var columnsCsv = string.Join(", ", mapsInfo.Select(x => NpgsqlHelper.GetQualifiedName(x.ColumnInfo.ColumnName))); var copySql = $"COPY {keyDataTable} ({columnsCsv}) FROM STDIN (FORMAT BINARY)"; using (var importer = conn.BeginBinaryImport(copySql)) { foreach (var kd in keyData) { importer.StartRow(); foreach (var kp in mapsInfo) { importer.Write(kp.Property.GetValue(kd), kp.NpgsqlType); } } } var whereSql = string.Join(" AND ", mapsInfo.Select(x => $"source.{NpgsqlHelper.GetQualifiedName(x.ColumnInfo.ColumnName)}" + $" = {keyDataTable}.{NpgsqlHelper.GetQualifiedName(x.ColumnInfo.ColumnName)}")); var selectSql = $"SELECT source.* FROM ({source}) as source\n" + $"JOIN {keyDataTable} ON {whereSql}"; BulkSelectInterceptor.SetReplaceQuery(source.ToString(), selectSql); var result = source.ToList(); localTr?.Commit(); return(result); } catch { localTr?.Rollback(); throw; } finally { BulkSelectInterceptor.StopInterception(); } }