c#


Using DataTable as a Table Valued Parameter in EF Core 2.0


[Updated problem description]
We have a bulk import process for which we were passing IEnumerable<SqlDataRecord> as a Table Valued Parameter (TVP) to a Stored Proc, as DataTable Type was not available until EF Core 1.1. We just upgraded our project to use .Net Core 2.0 and started updating the code to use DataTable. The ExecuteSqlCommandAsync command started throwing an InvalidCastException.
Here are the exception details:
System.InvalidCastException occurred
HResult=0x80004002
Message=Failed to convert parameter value from a DataTable to a IEnumerable`1.
Source=<Cannot evaluate the exception source>
StackTrace:
at System.Data.SqlClient.SqlParameter.CoerceValue(Object value, MetaType destinationType, Boolean& coercedToDataFeed, Boolean& typeChanged, Boolean allowStreaming)
at System.Data.SqlClient.SqlParameter.GetCoercedValue()
at System.Data.SqlClient.SqlParameter.Validate(Int32 index, Boolean isCommandProc)
at System.Data.SqlClient.SqlCommand.BuildParamList(TdsParser parser, SqlParameterCollection parameters)
at System.Data.SqlClient.SqlCommand.BuildExecuteSql(CommandBehavior behavior, String commandText, SqlParameterCollection parameters, _SqlRPC& rpc)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean asyncWrite, String method)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName)
at System.Data.SqlClient.SqlCommand.BeginExecuteNonQuery(AsyncCallback callback, Object stateObject)
at System.Threading.Tasks.TaskFactory`1.FromAsyncImpl(Func`3 beginMethod, Func`2 endFunction, Action`1 endAction, Object state, TaskCreationOptions creationOptions)
at System.Threading.Tasks.TaskFactory`1.FromAsync(Func`3 beginMethod, Func`2 endMethod, Object state)
at System.Data.SqlClient.SqlCommand.ExecuteNonQueryAsync(CancellationToken cancellationToken)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.<ExecuteAsync>d__26.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.<ExecuteSqlCommandAsync>d__11.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at X.Y.Repositories.Repository.<Import>d__4.MoveNext() in Repository.cs:line 95
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at X.Y.Services.ImportService`2.<BulkImportAsync>d__6.MoveNext() in ImportService.cs:line 70
Inner Exception 1:
InvalidCastException: Object must implement IConvertible.
This is how I am calling the stored proc:
var dataTable = new DataTable();
dataTable.Columns.Add("Col1", typeof(String));
dataTable.Columns.Add("Col2", typeof(String)); //and so on
foreach (var record in records)
{
var row = dataTable.NewRow();
SetStringValue(row, "Col1", record.Field1); //SetStringValue is just a helper method that assigns DBNull.Value if the field value is null.
SetStringValue(row, "Col2", record.Field2); //and so on
dataTable.Rows.Add(row);
}
var param = new SqlParameter("#Records", dataTable)
{
TypeName = "TVPRecords",
SqlDbType = SqlDbType.Structured
};
await _dbContext.Database.ExecuteSqlCommandAsync("EXEC dbo.ImportData #Records", param);
With DataTable now available in EF Core 2.0, I still can't use it to pass as a TVP to a Stored Proc. Is it because its not supported yet or may be a bug?

Related Links

Using implicit typing [duplicate]
Pass a .sql file to SQL Server for execution
JSON deserialize with nested list in C#
Unit testing chained private methods in C#
Invoking WPF Dispatcher with anonymous method
How to make this code DRY?
ManagementScope and Win32_Product retrieving executable paths
Response.Redirect from one web project to another in Visual Studio
Insert rows into Access Table in order from c#
Host TCP Chat Server in IIS
hooks in function argument to accommodate future data?
Change datetime to date in MVC 3 C#
Default state of the systray icon
Help in understanding project euler's question #54
XtraGrid Questions
Add table dynamically in Entity framework in MVC

Categories

HOME
algolia
kendo-ui-angular2
data-modeling
assign
squeak
jshell
markdown
pip
olap
virtualenv
watson-dialog
web-testing
appsettings
nsoperation
game-engine
k-means
pylint
reportlab
samba
airbnb
conditional-formatting
keystone
monad-transformers
ajaxcontroltoolkit
vala
typedef
mattermost
matlab-gui
onclicklistener
policy
workflow-foundation
dynamic-memory-allocation
ocl
apm
openoffice-impress
choco
unity3d-5
bootcamp
gitosis
flex3
leaderboard
ng-lightning
ninja-forms
cakephp-3.2
api-key
django-cors-headers
runner
jtextarea
android-tabs
visual-web-developer
foreground
disconnect
jde
web-performance
windows-phone-8-emulator
om
exchange-server-2007
tess4j
textblob
hexagonal-tiles
gmaps4jsf
bungeecord
wingdb
mri
crtdbg.h
frisby.js
dirname
atg-dynamo
telerik-appbuilder
connections
pthreads-win32
netbeans-plugins
grunt-wiredep
cryptarithmetic-puzzle
nude.js
animationdrawable
datasheet
mysql-connector
jqzoom
virtual-printer
rjs
xpolog
qvariant
method-call
zipstream
cpack
virtual-destructor
subdirectories
dongle
appointment
lts
high-load
weak-typing

Resources

Encrypt Message



code
soft
python
ios
c
html
jquery
cloud
mobile