Import values from CSV into SQL Server - sql-server

I'm in need of importing CSV data from a client computer to a SQL Server which exists elsewhere on the network. I want to do this with PowerShell as I'm trying to become more fluent in using it.
However, when I use an example I've found on the internet I've run into an issue which I don't understand.
For reference I'm using the third example from:
http://blogs.technet.com/b/heyscriptingguy/archive/2011/11/28/four-easy-ways-to-import-csv-files-to-sql-server-with-powershell.aspx
I've got the information importing into the datatable, however it appears that once the system tries to insert the data into the database I get the following error which is apparently an issue with how my data is getting into my datatable because the at symbol and bracket seem to be causing the issue.
This is the error:
System.Management.Automation.MethodException: Cannot convert argument "0", with value: "System.Object[]", for "WriteToServer" to
type "System.Data.DataRow[]":
"Cannot convert the "#{[Type]=1; [EID]=803; [FirstName]=Bob; [MiddleInit]=; [LastName]=Miller; [HireDate]=03031903; [Rule]=H;
[Rate]=0100; [Status]=1; [Store]=8; [Dept]=04; [Class]=130;
[Badge]=803;}" value of type
"System.Management.Automation.PSCustomObject" to type "System.Data.DataRow"."
---> System.Management.Automation.PSInvalidCastException: Cannot convert
the "#{[Type]=1; [EID]=803; [FirstName]=Bob; [MiddleInit]=;
[LastName]=Miller; [HireDate]=03031903; [Rule]=H; [Rate]=0100;
[Status]=1; [Store]=8; [Dept]=04; [Class]=130; [Badge]=803;}" value of
type "System.Management.Automation.PSCustomObject" to type
"System.Data.DataRow".
at System.Management.Automation.LanguagePrimitives.ConvertTo(Object
valueToConvert, Type resultType, Boolean recursion, IFormatProvider
formatProvider, TypeTable backupTypeTable)
at System.Management.Automation.LanguagePrimitives.ConvertUnrelatedArrays(Object
valueToConvert, Type resultType, Boolean recursion, PSObject
originalValueToConvert, IFormatProvider formatProvider, TypeTable backupTable)
at System.Management.Automation.LanguagePrimitives.ConvertTo(Object
valueToConvert, Type resultType, Boolean recursion, IFormatProvider
formatProvider, TypeTable backupTypeTable)
at System.Management.Automation.Adapter.PropertySetAndMethodArgumentConvertTo(Object
valueToConvert, Type resultType, IFormatProvider formatProvider)
at System.Management.Automation.Adapter.MethodArgumentConvertTo(Object
valueToConvert, Boolean isParameterByRef, Int32 parameterIndex, Type
resultType, IFormatProvider formatProvider)
at System.Management.Automation.Adapter.SetNewArgument(String methodName, Object[] arguments, Object[] newArguments,
ParameterInformation parameter, Int32 index)
--- End of inner exception stack trace ---
at System.Management.Automation.Adapter.SetNewArgument(String methodName, Object[] arguments, Object[] newArguments,
ParameterInformation parameter, Int32 index)
at System.Management.Automation.Adapter.GetMethodArgumentsBase(String
methodName, ParameterInformation[] parameters, Object[] arguments,
Boolean expandParamsOnBest)
at System.Management.Automation.DotNetAdapter.MethodInvokeDotNet(String
methodName, Object target, MethodInformation[] methodInformation,
Object[] arguments)
at System.Management.Automation.Adapter.BaseMethodInvoke(PSMethod method,
Object[] arguments)
at System.Management.Automation.ParserOps.CallMethod(Token token, Object target, String methodName, Object[] paramArray, Boolean
callStatic, Object valueToSet)
at System.Management.Automation.MethodCallNode.InvokeMethod(Object
target, Object[] arguments, Object value)
at System.Management.Automation.MethodCallNode.Execute(Array input, Pipe outputPipe, ExecutionContext context)
at System.Management.Automation.ParseTreeNode.Execute(Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context)
at System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode
statement, Array input, Pipe outputPipe, ArrayList& resultList,
ExecutionContext context)
Message + CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Write-DataTable.PS1

Related

Convert.FromBase64String not working after v14 Upgrade

We just upgraded our 2sxc custom API to v14, and now we're having an issue in an API controller that's used for uploading files with converting from Base64 to a byte array. Here's the code:
public class IntegrationApiController : Custom.Hybrid.Api14
{
[HttpPost]
public string UploadPdf([FromBody] dynamic bodyJson)
{
var entity = new Dictionary<string, object>();
var guid = Guid.NewGuid();
entity.Add("EntityGuid", guid);
App.Data.Create("PDFForm", entity);
var data = Convert.FromBase64String(bodyJson.file.ToString());
var returnThing = SaveInAdam(stream: new MemoryStream(data), fileName: bodyJson.fileName.ToString(), contentType: "PDFForm", guid: guid, field: "File");
return returnThing.Url;
}
}
We're getting the following error now:
{
"Message": "2sxc Api Controller Finder Error: Error selecting / compiling an API controller. Check event-log, code and inner exception. ",
"ExceptionMessage": "c:\\Websites\\Mainstar\\Portals\\0\\2sxc\\DocusignForms\\api\\IntegrationApiController.cs(26): error CS1061: 'ToSic.Sxc.Services.IConvertService' does not contain a definition for 'FromBase64String' and no extension method 'FromBase64String' accepting a first argument of type 'ToSic.Sxc.Services.IConvertService' could be found (are you missing a using directive or an assembly reference?)",
"ExceptionType": "System.Web.HttpCompileException",
"StackTrace": " at System.Web.Compilation.AssemblyBuilder.Compile()\r\n at System.Web.Compilation.BuildProvidersCompiler.PerformBuild()\r\n at System.Web.Compilation.BuildManager.CompileWebFile(VirtualPath virtualPath)\r\n at System.Web.Compilation.BuildManager.GetVPathBuildResultInternal(VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)\r\n at System.Web.Compilation.BuildManager.GetVPathBuildResultWithNoAssert(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean throwIfNotFound, Boolean ensureIsUpToDate)\r\n at System.Web.Compilation.BuildManager.GetVPathBuildResult(HttpContext context, VirtualPath virtualPath, Boolean noBuild, Boolean allowCrossApp, Boolean allowBuildInPrecompile, Boolean ensureIsUpToDate)\r\n at System.Web.Compilation.BuildManager.GetCompiledAssembly(String virtualPath)\r\n at ToSic.Sxc.Dnn.WebApiRouting.AppApiControllerSelector.HttpControllerDescriptor(HttpRequestMessage request, String controllerFolder, String controllerPath, String controllerTypeName, LogCall`1 wrapLog) in C:\\Projects\\2sxc\\2sxc\\Src\\Dnn\\ToSic.Sxc.Dnn.WebApi\\Dnn\\WebApiRouting\\AppApiControllerSelector.cs:line 168\r\n at ToSic.Sxc.Dnn.WebApiRouting.AppApiControllerSelector.SelectController(HttpRequestMessage request) in C:\\Projects\\2sxc\\2sxc\\Src\\Dnn\\ToSic.Sxc.Dnn.WebApi\\Dnn\\WebApiRouting\\AppApiControllerSelector.cs:line 83"
}
Any ideas how to fix this? I did try changing "Convert.FromBase64String" to "System.Convert.FromBase64String" and that didn't solve the issue - I got a "Cannot perform runtime binding on a null reference" error instead.
Any help would be greatly appreciated!
System.Convert... sounds right. And IMHO should work.
My guess is that your bodyJson or bodyJson.file is null.

SerialPort read in extension fails on dotnet error

I'm writing an extension that reads serial port data. I'm running on BC14 OnPremis.
Here is what I have. The global variable, running on client side (obviously serioal port is not on the server, with events because I need to receive data somehow.
var
[RunOnClient]
[WithEvents]
Port: DotNet SerialPortA;
The trigger which is called when data on port is available. It is actually fired.
trigger Port::DataReceived(sender: Variant; e: DotNet SerialDataReceivedEventArgs)
var
CurrPort: DotNet SerialPortA;
BarText: DotNet String;
begin
CurrPort := sender;
BarText := CurrPort.ReadLine();
Message(BarText);
end;
In the dotne.al file I have a declaration for SerialPort type. For some reasons it confused name with something else so I had to add a suffix to type alias. So now my type is called SerialPortA.
assembly("System")
{
Version = '4.0.0.0';
Culture = 'neutral';
PublicKeyToken = 'b77a5c561934e089';
type("System.IO.Ports.SerialPort"; "SerialPortA") { }
type("System.IO.Ports.SerialDataReceivedEventArgs"; "SerialDataReceivedEventArgs") { }
type("System.IO.Ports.SerialErrorReceivedEventArgs"; "SerialErrorReceivedEventArgs") { }
}
The problem is that a call to CurrPort.ReadLine() fails with error:
A call to System.Object.ReadLine failed with this message: The type of one or more arguments does not match the method's parameter type.
I tried to use another method Read. The error is the same. It is most probably related to Nav wrapping/unwrapping all dotnet variables to object type, but I don't know what ca I do with thath. Any guess what is going wrong here?
In the event log there is an error description
Server instance: N721
Category: Runtime
ClientSessionId: b6d2f654-0601-46b7-bd70-ae4fa637d422
ClientActivityId: 75ab980f-28d2-4a47-8d50-787c132c854c
ServerSessionUniqueId: cc752b06-1eab-43ed-8976-f1973da11ae5
ServerActivityId: fbc48c73-482c-4f84-87e3-4b3b1765dc5b
EventTime: 10/08/2020 06:29:21
Message ObjectType: System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
MethodName: ReadLine
BindingFlags: Instance, Public, InvokeMethod
ProcessId: 24200
Tag: 000010P
ThreadId: 199
CounterInformation:
And another one
Server instance: N721
Category: Runtime
ClientSessionId: b6d2f654-0601-46b7-bd70-ae4fa637d422
ClientActivityId: 75ab980f-28d2-4a47-8d50-787c132c854c
ServerSessionUniqueId: cc752b06-1eab-43ed-8976-f1973da11ae5
ServerActivityId: fbc48c73-482c-4f84-87e3-4b3b1765dc5b
EventTime: 10/08/2020 06:29:21
Message (NavNCLDotNetInvokeException): This message had personal data removed. The original may still be in transient telemetry. Find it using the transientTelemetryId.
ParentException: NavNCLDotNetInvokeException
A call to System.Object.ReadLine failed with this message: The type of one or more arguments does not match the method's parameter type.
ExceptionStackTrace:
at Microsoft.Dynamics.Nav.Runtime.NavApplicationMethod.InvokeMethod(ITreeObject obj, String methodName, Object[] args, Boolean resolveHandler, Boolean throwOnNotFound)
at Microsoft.Dynamics.Nav.Service.NSField.InvokeEventTriggerInternal(NavSession con, String eventName)
at Microsoft.Dynamics.Nav.Service.NSField.InvokeEventTrigger(NavSession session, String eventName)
at SyncInvokeInvokeEventTrigger(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.RunInTransactionCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.TransientErrorRetryCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.ErrorMappingCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
InnerException:
ParentException: TargetInvocationException
ExceptionStackTrace:
at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor)
at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at Microsoft.Dynamics.Nav.Runtime.NavApplicationMethod.InvokeMethod(ITreeObject obj, String methodName, Object[] args, Boolean resolveHandler, Boolean throwOnNotFound)
InnerException:
RootException: NavNCLDotNetInvokeException
A call to System.Object.ReadLine failed with this message: The type of one or more arguments does not match the method's parameter type.
ExceptionStackTrace:
at Microsoft.Dynamics.Nav.Types.NavAutomationHelper.GetMethodInfo(String methodName, Type objectType, BindingFlags binding, ParameterModifier[] modifier, Object[] arguments, Type[] referenceTypes)
at Microsoft.Dynamics.Nav.Runtime.NavDotNet.Invoke[T](String methodName, UInt32 methodIndex, BindingFlags flags, ParameterModifier modifier, Type[] referenceTypes, Object[] arguments)
at Microsoft.Dynamics.Nav.Runtime.NavDotNet.InvokeMethod[T](Boolean isStatic, String methodName, UInt32 methodIndex, Object[] arguments)
at Microsoft.Dynamics.Nav.BusinessApplication.Page1057905.Porta58a58DataReceived_Scope.OnRun()
at Microsoft.Dynamics.Nav.Runtime.NavMethodScope.Run()
at Microsoft.Dynamics.Nav.BusinessApplication.Page1057905.Porta58a58DataReceived(NavVariant sender, NavDotNet e)
CallerStackTrace:
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.ErrorMappingCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.PushPopCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationTracer.TraceScopeCombinator(Category telemetryCategory, ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass10_0.<PerformanceCounterCombinator>b__0()
at Microsoft.Dynamics.Nav.Runtime.NavPerformanceCounterSetter.UpdatePerformanceCountersWithAverageServiceOperationDuration(Stopwatch stopWatch, Action action)
at Microsoft.Dynamics.Nav.Runtime.NavPerformanceCounterSetter.UpdatePerformanceCountersWithAverageServiceOperationAction(Action action, NavSession session)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.PerformanceCounterCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.InitClientTelemetryIdsCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.TlsClearCombinator(ServiceOperation innerOperation, NSServiceBase serviceInstance, MethodBase syncMethod, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.<>c__DisplayClass28_1.<Combine>b__1(NSServiceBase serviceInstance, Object[] inputs, Object[]& outputs)
at Microsoft.Dynamics.Nav.Service.ServiceOperationInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
at System.ServiceModel.Dispatcher.MessageRpc.Wrapper.Resume(Boolean& alreadyResumedNoLock)
at System.ServiceModel.Dispatcher.ThreadBehavior.ResumeProcessing(IResumeMessageRpc resume)
at Microsoft.Dynamics.Nav.Runtime.NavSynchronizationContext.<>c__DisplayClass1_0.<ClearThreadLocalStorageDelegate>b__0(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
ProcessId: 24200
Tag: 00000HC
ThreadId: 199
CounterInformation:
I don't have a serial port to test with, so this is of the top of my mind.
You probably need to cast the variant to the correct type:
trigger Port::DataReceived(sender: Variant; e: DotNet SerialDataReceivedEventArgs)
var
Type: DotNet Type;
Convert: DotNet Convert;
CurrPort: DotNet SerialPortA;
BarText: DotNet String;
begin
// This check is just best pratice, but not needed in this case as we know sender is a SerialPort.
if not sender.IsDotNet() then
exit;
Type := GetDotNetType(sender);
CurrPort := Convert.ChangeType(sender, Type);
BarText := CurrPort.ReadLine();
Message(BarText);
end;

Npgsql connection to PostgreSql: Array datatype

I am working in Visual Studio 2015 using Visual Basic. I am connecting to a PostgreSql database using Npgsql. There seems to be a problem with the Array Datatype - or hopefully I am doing something wrong. Some of my code:
Dim aWriter As Npgsql.NpgsqlBinaryImporter
Dim Keys() As String
N_Domain = UBound(myKey_Name, 1)
N_Record = UBound(myKey_Name, 2)
ReDim Keys(0 To N_Domain - 1)
aWriter = Connect.BeginBinaryImport _
("COPY ""GAMS Sets"" FROM STDIN (FORMAT BINARY)")
For Rec = 1 To N_Record
For Dom = 1 To N_Domain
Keys(Dom - 1) = myKey_Name(Dom, Rec)
Next Dom
aWriter.StartRow()
aWriter.Write(myCase, NpgsqlDbType.Text)
aWriter.Write(SyId, NpgsqlDbType.Text)
aWriter.Write(Keys, NpgsqlDbType.Array Or NpgsqlDbType.Text)
Next Rec
aWriter.Dispose()
aWriter.Close()
When I run the code I get an error at aWriter.Dispose():
{"42804: wrong element type"}, ErrorCode: -2147467259.
What is wrong? Isn't Text Arrays supported?
Error details:
Npgsql.PostgresException was unhandled
BaseMessage=wrong element type
Code=42804
ErrorCode=-2147467259
File=arrayfuncs.c
HResult=-2147467259
InternalPosition=0
Line=1306
Message=42804: wrong element type
MessageText=wrong element type
Position=0
Routine=array_recv
Severity=ERROR
Source=Npgsql
SqlState=42804
[Where]=COPY GAMS Sets, line 1, column Keys
StackTrace:
at Npgsql.NpgsqlConnector.DoReadMessage(DataRowLoadingMode dataRowLoadingMode, Boolean isPrependedMessage)
at Npgsql.NpgsqlConnector.ReadMessageWithPrepended(DataRowLoadingMode dataRowLoadingMode)
at Npgsql.NpgsqlConnector.ReadExpecting[T]()
at Npgsql.NpgsqlBinaryImporter.Close()
at Npgsql.NpgsqlBinaryImporter.Dispose()
at ConsoleApplication1.Module1.HVL_Write_Set(String myCase, Int32 SyNr, String SyId, Int32 Dimen, String[] myDomain_Name, String[,] myKey_Name) in \\dtu-storage\hela\Documents\Visual Studio 2015\Projects\GDX API 5\GDX API 5\Module1.vb:line 305
at ConsoleApplication1.Module1.Main() in \\dtu-storage\hela\Documents\Visual Studio 2015\Projects\GDX API 5\GDX API 5\Module1.vb:line 638
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:

Passing an array to a function is extremely slow

I have written a PowerShell script that requires passing large byte arrays between functions. The script runs extremely slowly. The sample code below reproduces the problem. It simply passes a 10 MiB array into a function that does nothing (other than log a message), and measures how long the call takes.
function do-nothing
{
param($foo)
Write-Verbose -Verbose "in the function"
}
$tenMiB = 10 * 1024 * 1024
$myFoo = New-Object byte[] $tenMiB
Write-Verbose -Verbose "about to do call a function that does nothing..."
$elapsed = Measure-Command -Expression { do-nothing -foo $myFoo }
Write-Verbose -Verbose "doing nothing took $($elapsed.TotalMilliseconds) milliseconds"
I expect this to take a few milliseconds. On my home PC it takes nearly 3000 ms and runs a CPU core at 100%. I get the same result with PowerShell 4 and PowerShell 5 (pre-production version). The same thing happens with my work PC and servers. However, one colleague gets the expected result - a few milliseconds to execute, minimal CPU usage.
The execution time is roughly proportional to the size of the array, which makes no sense to me. The size of the array should not matter.
I wondered if the array was somehow being copied. I do not think this is the case because calling GetHashCode() on the array returns the same value inside and outside of the function.
If the array is wrapped in a PSCustomObject, and the wrapper is passed to the function, then the code performs as expected. This is a bit ugly as a workaround, and I'd rather understand what is going on before resorting to it.
Can anyone explain this seemingly weird behaviour please?
I'm posting this as a community wiki, intended to be a place where we can post our individual environments and test results, since there seems to be some trouble reproducing. Maybe we can figure out the conditions that cause this, and from there determine why it's slow in the instances that it is. Formatting suggestions / changes welcome.
briantist
Workstation
HW (i7)
Windows 8.1
PowerShell 4.0
ISE and Console
Domain joined
byte[] Result: ~3,500ms
object[] Result: ~6,500ms
Server VM
VM (VMware ESXi)
Windows 2012 R2
PowerShell 5.0.10514.6 (Production Preview)
ISE
Domain joined
byte[] Result: > 7,000ms
object[] Result: ~100ms
Home Workstation
HW (i5)
Windows 10 build 1511
PowerShell 5
ISE and Console
Workgroup (No AD)
Result: 4-6ms first run, < 2ms subsequent runs
emanresu
PowerShell 4
Result: 1.8 - 2.4ms
Bacon Bits
Workstation
Windows 7 x64 SP1
Domain joined
PowerShell 4
Result: 100 executions, average of 1.16ms, min 0.67ms, max 13.88ms, 1.39ms stddev
VM (ESXi)
Windows Server 2012 R2
Domain joined
PowerShell 4
Result: 10 executions, average of 4221ms, min 4173ms, max 4302ms, 38.54ms stddev
Ansgar Wiechers
VM (VirtualBox)
Windows 2012 R2 (vanilla install)
PowerShell 4
CLRVersion: 4.0.30319.34014
BuildVersion: 6.3.9600.16394
Result: ~7.5ms
Windows 2012 R2 (same VM, fully patched)
PowerShell 4
CLRVersion: 4.0.30319.34209
BuildVersion: 6.3.9600.17400
Result: ~4000ms
Further investigation revealed that the issue was introduced by the November 2014 update rollup (MSKB 3000850). Not sure which of the collected hotfixes is the actual culprit, though.
beatcracker
Desktop
HW: Q6600#3.1 GHz/8GB RAM
Windows Server 2012
Workgroup (No AD)
PowerShell 5 (5.0.10018.0)
ISE and Console
Result: ~5000ms
Laptop
HW: i3#2.5 GHz/4GB RAM
Windows 8.1
Domain-joined PC
PowerShell 4
ISE and Console
Result: ~6000ms
David Brabant
PowerShell 5
Windows 10
Result: < 7 ms
sodawillow
HW (i5)
Windows 8.1
Workgroup (No AD)
PowerShell 5.0.10514.6
ISE
Result: > 3500 ms
Mathias R. Jessen
Home laptop
HW (i7-2620M)
Windows 10 (build 10240)
PowerShell 5.0
ISE and Console
byte[] Result: ~5,350ms
object[] Result: ~8,500ms
int[] Result: ~9,700ms
Thanks to stack traces posted by #Ansgar Wiechers, I was able to reproduce this behavior on my PC (Windows 10 build 1511, PowerShell 5.0.10586.0) with following code:
$Module = New-Module {
function do-nothing
{
param($foo)
Write-Verbose -Verbose "in the function"
}
}
$Module.LogPipelineExecutionDetails = $true
$myFoo = New-Object byte[] 10mb
Write-Verbose -Verbose "about to do call a function that does nothing..."
$elapsed = Measure-Command -Expression { do-nothing -foo $myFoo }
Write-Verbose -Verbose "doing nothing took $($elapsed.TotalMilliseconds) milliseconds"
Enabling LogPipelineExecutionDetails cause large slowdown of function execution. Judging from my digging with ILSpy, logging of pipeline execution details should be enabled only if function belong to module and module enable this option. Maybe that is exact behavior which kb3000850 altering.
It would be interesting to see if problem reproduced when do-nothing belong to module, but LogPipelineExecutionDetails explicitly set to $false.
Supplementary information, posted as an additional community wiki answer to avoid the character limit per answer.
As requested by #PetSerAl I ran the following code before and after installing kb3000850:
Add-Type -TypeDefinition #'
public static class C{
public static System.Collections.IEnumerable M(){
System.Console.WriteLine(new System.Diagnostics.StackTrace());
yield break;
}
}
'#
function do-nothing {
param($foo)
Write-Verbose -Verbose "in the function"
}
$myFoo = [C]::M()
Write-Verbose -Verbose "about to do call a function that does nothing..."
$elapsed = Measure-Command -Expression { do-nothing -foo $myFoo }
Write-Verbose -Verbose "doing nothing took $($elapsed.TotalMilliseconds) milliseconds"
Stacktrace before update:
at C.<M>d__0.MoveNext()
at System.Management.Automation.PSObject.ToStringEnumerable(ExecutionContext context, IEnumerable enumerable, String separator, String format, IFormatProvider formatProvider)
at System.Management.Automation.PSObject.ToString(ExecutionContext context, Object obj, String separator, String format, IFormatProvider formatProvider, Boolean recurse, Boolean unravelEnumeratorOnRecurse)
at System.Management.Automation.PSObject.ToStringParser(ExecutionContext context, Object obj)
at System.Management.Automation.LanguagePrimitives.ConvertNonNumericToString(Object valueToConvert, Type resultType, Boolean recursion, PSObject originalValueToConvert, IFormatProvider formatProvider, TypeTable backupTable)
at System.Management.Automation.LanguagePrimitives.ConversionData`1.Invoke(Object valueToConvert, Type resultType, Boolean recurse, PSObject originalValueToConvert, IFormatProvider formatProvider, TypeTable backupTable)
at System.Management.Automation.LanguagePrimitives.ConvertTo(Object valueToConvert, Type resultType, Boolean recursion, IFormatProvider formatProvider, TypeTable backupTypeTable)
at System.Management.Automation.ParameterBinderBase.CoerceTypeAsNeeded(CommandParameterInternal argument, String parameterName, Type toType, ParameterCollectionTypeInformation collectionTypeInfo, Object currentValue)
at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
at System.Management.Automation.CmdletParameterBinderController.BindParameter(CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
at System.Management.Automation.CmdletParameterBinderController.BindParameter(UInt32 parameterSets, CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
at System.Management.Automation.ParameterBinderController.BindPositionalParametersInSet(UInt32 validParameterSets, Dictionary`2 nextPositionalParameters, CommandParameterInternal argument, ParameterBindingFlags flags, ParameterBindingException& bindingException)
at System.Management.Automation.ParameterBinderController.BindPositionalParameters(Collection`1 unboundArguments, UInt32 validParameterSets, UInt32 defaultParameterSet, ParameterBindingException& outgoingBindingException)
at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParametersNoValidation(Collection`1 arguments)
at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
at System.Management.Automation.CommandProcessor.BindCommandLineParameters()
at System.Management.Automation.CommandProcessorBase.DoPrepare(IDictionary psDefaultParameterValues)
at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(CommandProcessorBase commandRequestingUpstreamCommandsToStop)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.ScriptBlock.InvokeWithPipeImpl(ScriptBlockClauseToInvoke clauseToInvoke, Boolean createLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Object[] args)
at System.Management.Automation.ScriptBlock.<>c__DisplayClassa.<InvokeWithPipe>b__8()
at System.Management.Automation.Runspaces.RunspaceBase.RunActionIfNoRunningPipelinesWithThreadCheck(Action action)
at System.Management.Automation.ScriptBlock.InvokeWithPipe(Boolean useLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Object[] args)
at Microsoft.PowerShell.Commands.MeasureCommandCommand.ProcessRecord()
at System.Management.Automation.CommandProcessor.ProcessRecord()
at System.Management.Automation.CommandProcessorBase.DoExecute()
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(CommandProcessorBase commandRequestingUpstreamCommandsToStop)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(CommandProcessorBase commandRequestingUpstreamCommandsToStop)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.Runspaces.LocalPipeline.InvokeHelper()
at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProc()
at System.Management.Automation.Runspaces.PipelineThread.WorkerProc()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Stacktrace after update (differences highlighted):
at C.<M>d__0.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
at System.Management.Automation.ParameterBinderController.BindParameter(UInt32 parameterSets, CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
at System.Management.Automation.ScriptParameterBinderController.BindParameters(Collection`1 arguments)
at System.Management.Automation.ScriptParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
at System.Management.Automation.DlrScriptCommandProcessor.EnterScope()
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
at System.Management.Automation.DlrScriptCommandProcessor.Complete()
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(CommandProcessorBase commandRequestingUpstreamCommandsToStop)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.ScriptBlock.InvokeWithPipeImpl(ScriptBlockClauseToInvoke clauseToInvoke, Boolean createLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Object[] args)
at System.Management.Automation.ScriptBlock.<>c__DisplayClassa.<InvokeWithPipe>b__8()
at System.Management.Automation.Runspaces.RunspaceBase.RunActionIfNoRunningPipelinesWithThreadCheck(Action action)
at System.Management.Automation.ScriptBlock.InvokeWithPipe(Boolean useLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Object[] args)
at Microsoft.PowerShell.Commands.MeasureCommandCommand.ProcessRecord()
at System.Management.Automation.CommandProcessor.ProcessRecord()
at System.Management.Automation.CommandProcessorBase.DoExecute()
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
at System.Management.Automation.DlrScriptCommandProcessor.Complete()
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(CommandProcessorBase commandRequestingUpstreamCommandsToStop)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
at System.Management.Automation.DlrScriptCommandProcessor.Complete()
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(CommandProcessorBase commandRequestingUpstreamCommandsToStop)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.Runspaces.LocalPipeline.InvokeHelper()
at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProc()
at System.Management.Automation.Runspaces.PipelineThread.WorkerProc()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
at C.<M>d__0.MoveNext()
at System.Management.Automation.PSObject.ToStringEnumerable(ExecutionContext context, IEnumerable enumerable, String separator, String format, IFormatProvider formatProvider)
at System.Management.Automation.PSObject.ToString(ExecutionContext context, Object obj, String separator, String format, IFormatProvider formatProvider, Boolean recurse, Boolean unravelEnumeratorOnRecurse)
at System.Management.Automation.PSObject.ToStringParser(ExecutionContext context, Object obj)
at System.Management.Automation.LanguagePrimitives.ConvertNonNumericToString(Object valueToConvert, Type resultType, Boolean recursion, PSObject originalValueToConvert, IFormatProvider formatProvider, TypeTable backupTable)
at System.Management.Automation.LanguagePrimitives.ConversionData`1.Invoke(Object valueToConvert, Type resultType, Boolean recurse, PSObject originalValueToConvert, IFormatProvider formatProvider, TypeTable backupTable)
at System.Management.Automation.LanguagePrimitives.ConvertTo(Object valueToConvert, Type resultType, Boolean recursion, IFormatProvider formatProvider, TypeTable backupTypeTable)
at System.Management.Automation.LanguagePrimitives.ConvertTo(Object valueToConvert, Type resultType, IFormatProvider formatProvider)
at System.Management.Automation.ParameterBinderBase.CoerceTypeAsNeeded(CommandParameterInternal argument, String parameterName, Type toType, ParameterCollectionTypeInformation collectionTypeInfo, Object currentValue)
at System.Management.Automation.ParameterBinderBase.BindParameter(CommandParameterInternal parameter, CompiledCommandParameter parameterMetadata, ParameterBindingFlags flags)
at System.Management.Automation.CmdletParameterBinderController.BindParameter(CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
at System.Management.Automation.CmdletParameterBinderController.BindParameter(UInt32 parameterSets, CommandParameterInternal argument, MergedCompiledCommandParameter parameter, ParameterBindingFlags flags)
at System.Management.Automation.ParameterBinderController.BindPositionalParametersInSet(UInt32 validParameterSets, Dictionary`2 nextPositionalParameters, CommandParameterInternal argument, ParameterBindingFlags flags, ParameterBindingException& bindingException)
at System.Management.Automation.ParameterBinderController.BindPositionalParameters(Collection`1 unboundArguments, UInt32 validParameterSets, UInt32 defaultParameterSet, ParameterBindingException& outgoingBindingException)
at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParametersNoValidation(Collection`1 arguments)
at System.Management.Automation.CmdletParameterBinderController.BindCommandLineParameters(Collection`1 arguments)
at System.Management.Automation.CommandProcessor.BindCommandLineParameters()
at System.Management.Automation.CommandProcessorBase.DoPrepare(IDictionary psDefaultParameterValues)
at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
at System.Management.Automation.DlrScriptCommandProcessor.Complete()
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(CommandProcessorBase commandRequestingUpstreamCommandsToStop)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.ScriptBlock.InvokeWithPipeImpl(ScriptBlockClauseToInvoke clauseToInvoke, Boolean createLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Object[] args)
at System.Management.Automation.ScriptBlock.<>c__DisplayClassa.<InvokeWithPipe>b__8()
at System.Management.Automation.Runspaces.RunspaceBase.RunActionIfNoRunningPipelinesWithThreadCheck(Action action)
at System.Management.Automation.ScriptBlock.InvokeWithPipe(Boolean useLocalScope, Dictionary`2 functionsToDefine, List`1 variablesToDefine, ErrorHandlingBehavior errorHandlingBehavior, Object dollarUnder, Object input, Object scriptThis, Pipe outputPipe, InvocationInfo invocationInfo, Object[] args)
at Microsoft.PowerShell.Commands.MeasureCommandCommand.ProcessRecord()
at System.Management.Automation.CommandProcessor.ProcessRecord()
at System.Management.Automation.CommandProcessorBase.DoExecute()
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
at System.Management.Automation.DlrScriptCommandProcessor.Complete()
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(CommandProcessorBase commandRequestingUpstreamCommandsToStop)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.PipelineOps.InvokePipeline(Object input, Boolean ignoreInput, CommandParameterInternal[][] pipeElements, CommandBaseAst[] pipeElementAsts, CommandRedirection[][] commandRedirections, FunctionContext funcContext)
at System.Management.Automation.Interpreter.ActionCallInstruction`6.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.Interpreter.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.LightLambda.RunVoid1[T0](T0 arg0)
at System.Management.Automation.DlrScriptCommandProcessor.RunClause(Action`1 clause, Object dollarUnderbar, Object inputToProcess)
at System.Management.Automation.DlrScriptCommandProcessor.Complete()
at System.Management.Automation.CommandProcessorBase.DoComplete()
at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(CommandProcessorBase commandRequestingUpstreamCommandsToStop)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input, Hashtable errorResults, Boolean enumerate)
at System.Management.Automation.Runspaces.LocalPipeline.InvokeHelper()
at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProc()
at System.Management.Automation.Runspaces.PipelineThread.WorkerProc()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
VERBOSE: about to do call a function that does nothing...
VERBOSE: in the function
VERBOSE: doing nothing took 9345.0445 milliseconds
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_ref?view=powershell-7.1#writing-functions-to-accept-reference-parameters
function do-nothing
{
param([ref]$foo)
# When using references, you must use the Value property of
# the System.Management.Automation.PSReference type to access your data.
$foo.Value
Write-Verbose -Verbose "in the function"
}
$tenMiB = 10 * 1024 * 1024
$myFoo = New-Object byte[] $tenMiB
Write-Verbose -Verbose "about to do call a function that does nothing..."
$elapsed = Measure-Command -Expression { do-nothing -foo ([ref]$myFoo) }
Write-Verbose -Verbose "doing nothing took $($elapsed.TotalMilliseconds) milliseconds"
_
VERBOSE: about to do call a function that does nothing...
VERBOSE: in the function
VERBOSE: doing nothing took 1303.8049 milliseconds

Retrieving XML from database with Dapper

I am using Dapper to query a table that includes an XML field:
CREATE TABLE Workflow
(
Guid uniqueidentifier not null,
State xml not null
)
which is then mapped to a property of type XDocument:
public class Workflow
{
public Guid InstanceId { get;set; }
public XDocument State { get;set; }
}
but when I try to query the table, I get the following error:
Error parsing column 1 (State= - String)
at Dapper.SqlMapper.ThrowDataException(Exception ex, Int32 index, IDataReader reader, Object value) in d:\\Dev\\dapper-dot-net\\Dapper NET40\\SqlMapper.cs:line 4045
at Deserialize038b29f4-d97d-4b62-b45b-786bd7d50e7a(IDataReader )
at Dapper.SqlMapper.<QueryImpl>d__11`1.MoveNext() in d:\\Dev\\dapper-dot-net\\Dapper NET40\\SqlMapper.cs:line 1572
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Dapper.SqlMapper.Query[T](IDbConnection cnn, String sql, Object param, IDbTransaction transaction, Boolean buffered, Nullable`1 commandTimeout, Nullable`1 commandType) in d:\\Dev\\dapper-dot-net\\Dapper NET40\\SqlMapper.cs:line 1443
at MyProject.DapperBase.Query[TResult](String command, DynamicParameters parameters, IDbTransaction transaction, Boolean buffered, Int32 commandTimeout) in d:\\MyProject\\DapperBase.cs:line 122
at MyProject.WorkflowData.Get(Guid identifier) in d:\\MyProject\\WorkflowData.cs:line 41
at MyProject.WorkflowLogic.Save(Workflow workflow) in d:\\MyProject\\WorkflowLogic.cs:line 34
at MyProject.WorkflowsController.Save(Guid id, WorkflowRequest request) in d:\\MyProject\\WorkflowsController.cs:line 97
InnerException: Invalid cast from 'System.String' to 'System.Xml.Linq.XDocument'.
at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider)at System.String.System.IConvertible.ToType(Type type, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider)
at System.Convert.ChangeType(Object value, Type conversionType)
at Deserialize038b29f4-d97d-4b62-b45b-786bd7d50e7a(IDataReader )
Other than modifying my POCO to use a string datatype and then convert the string into an XDocument elsewhere, is there a way of getting Dapper to correctly deserialise the XML from the database?
In the end, I just brute-forced it:
public class Workflow
{
public Guid InstanceId { get;set; }
public XDocument StateIn { set { State = value.ToString(); } }
public string State { get;set; }
public XDocument StateOut { get { return XDocument.Parse(State); } }
}
Dapper plays with the State value, and I just set the value on StateIn and read it off StateOut. I feel a little bit dirty coming up with a solution like this, but hey, it works.
Perhaps creating a custom type handler can help? Something like:
public class XDocumentTypeHandler : SqlMapper.TypeHandler<XDocument>
{
public override void SetValue(IDbDataParameter parameter, XDocument value)
{
// set value in db parameter.
}
public XDocument Parse(object value)
{
// parse value from db to an XDocument.
}
}
You have to add the type handler with SqlMapper.AddTypeHandler().
See a sample implementation.

Resources