internal/functions/providers/Update-SldgEntityData.ps1
|
function Update-SldgEntityData { <# .SYNOPSIS Writes masked rows back through the PSSqlRepository entity type. .DESCRIPTION The entity update path of masking mode. Every row of -Data becomes an instance of the table's entity type; Save-PSSqlRepositoryEntity -Mode Update loads the tracked rows by key in batches, copies the scalar values onto them and lets EF Core issue one UPDATE per changed row containing only the changed columns. Keys, identity values and every foreign key pointing at the table stay exactly as they were. EF's SetValues copies every mapped property, so the caller must hand over complete rows (the masking engine reads the table in full before masking). An explicit DbTransaction on the raw connection is enlisted on the EF context for the duration of the save. .PARAMETER ConnectionInfo The active SqlLabDataGenerator.Connection. .PARAMETER Binding The table binding from Get-SldgEntityBinding. .PARAMETER Data Complete rows, including the key column and the new values. .PARAMETER Transaction Optional DbTransaction opened on the connection to enlist in. .OUTPUTS System.Int32 - number of rows handed to the save. #> [OutputType([int])] [CmdletBinding()] param ( [Parameter(Mandatory)] [SqlLabDataGenerator.Connection]$ConnectionInfo, [Parameter(Mandatory)] [PSCustomObject]$Binding, [Parameter(Mandatory)] [System.Data.DataTable]$Data, [System.Data.Common.DbTransaction]$Transaction ) if ($Data.Rows.Count -eq 0) { return 0 } $entityType = $Binding.EntityType $setters = @{} foreach ($column in $Binding.Columns) { $setters[$column.Name] = $entityType.GetProperty($column.PropertyName) } $entities = [System.Collections.Generic.List[object]]::new($Data.Rows.Count) foreach ($row in $Data.Rows) { $entity = [System.Activator]::CreateInstance($entityType) foreach ($column in $Binding.Columns) { $value = $row[$column.Name] if ($value -is [DBNull]) { $value = $null } $property = $setters[$column.Name] if ($null -ne $value -and $value -isnot $column.DataType) { $value = [System.Convert]::ChangeType($value, $column.DataType, [System.Globalization.CultureInfo]::InvariantCulture) } $property.SetValue($entity, $value) } $entities.Add($entity) } $context = $ConnectionInfo.Repository.Session.Services.GetService([Microsoft.EntityFrameworkCore.DbContext]) $enlisted = $false try { if ($Transaction -and $context) { [void][Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions]::UseTransaction($context.Database, $Transaction) $enlisted = $true } $null = $entities | Save-PSSqlRepositoryEntity -EntityType $entityType -Mode Update -Confirm:$false -ErrorAction Stop } finally { if ($enlisted) { try { [void][Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions]::UseTransaction($context.Database, $null) } catch { $null = $_ } } } Write-PSFMessage -Level Verbose -String 'Entity.Updated' -StringValues $entities.Count, $Binding.Table.FullName, $entityType.FullName $entities.Count } |