private static async Task UpdateAsync()

in Backend/src/Trackable.EntityFramework/DbContextBulkOperations.cs [97:175]


        private static async Task UpdateAsync(
            DbContext context,
            string tableName,
            IDictionary<string, Type> idFields,
            IDictionary<string, Type> fieldsToUpdate,
            IEnumerable<List<Object>> rows)
        {
            var table = new DataTable();

            // Id fields are guaranteed to be primitives
            foreach (var idField in idFields)
            {
                table.Columns.Add(idField.Key, idField.Value);
            }

            var primitiveFields = new Dictionary<string, Type>();
            var excludedColumns = new List<int>();
            int index = idFields.Count;
            foreach (var column in fieldsToUpdate)
            {
                // DataTable does not support Nullable types, instead primitive types should be added
                // and the column marked as AllowDbNull
                if (column.Value.IsGenericType && column.Value.GetGenericTypeDefinition() == typeof(Nullable<>))
                {
                    DataColumn col = new DataColumn(column.Key, column.Value.GetGenericArguments().First());
                    col.AllowDBNull = true;
                    table.Columns.Add(col);

                    primitiveFields.Add(column.Key, column.Value.GetGenericArguments().First());
                }
                else if(SqlTypeHelper.GetDbType(column.Value).HasValue)
                {
                    table.Columns.Add(column.Key, column.Value);
                    primitiveFields.Add(column.Key, column.Value);
                }
                else
                {
                    // Column is unsupported type. Do not include it.
                    excludedColumns.Add(index);
                }

                index++; 
            }

            excludedColumns.Reverse();

            foreach (var row in rows)
            {
                foreach(var col in excludedColumns)
                {
                    row.RemoveAt(col);
                }

                table.Rows.Add(row.ToArray());
            }

            var connectionInitialState = context.Database.Connection.State;

            try
            {
                if (connectionInitialState != ConnectionState.Open)
                {
                    await context.Database.Connection.OpenAsync();
                }

                var typeName = await ExecuteTypeSqlCommand(context, tableName, idFields, primitiveFields);
                var storedProcedureName = await ExecuteStoredProcedureSqlCommand(context, tableName, typeName, idFields, primitiveFields);

                await ExecuteUpdateAsync(context, table, storedProcedureName, typeName);
            }
            finally
            {
                if (connectionInitialState != ConnectionState.Open)
                {
                    context.Database.Connection.Close();
                }
            }

        }