I'm trying to call a stored procedure from EntityFramework which uses Table-value parameter.
But when I try to do function import I keep getting a warning message saying -
The function 'InsertPerson' has a parameter 'InsertPerson_TVP' at parameter index 0 that has a data type 'table type' which is currently not supported for the target .NET Framework version. The function was excluded.
I did a initial search here and found few posts which says It's possible in EntityFrameWork with some work arounds and few saying it's not supported in current versions.
Does any one know a better approach or solution for this problem?
Step 1 − Select the Console Application from the middle pane and enter TableValuedFunctionDemo in the name field. Step 2 − In Server explorer right-click on your database. Step 3 − Select New Query and enter the following code in T-SQL editor to add a new table in your database.
Table-valued parameters are declared by using user-defined table types. You can use table-valued parameters to send multiple rows of data to a Transact-SQL statement or a routine, such as a stored procedure or function, without creating a temporary table or many parameters.
In this article I am explaining the use of Table Valued Parameters (TVPs) using Entity Framework. Table Valued Parameters (TVPs) were introduced in SQL Server 2008. TVPs allow passing multiple rows of data to the server.
To create an instance of a User-Defined Table Type or call a stored procedure with a Table-valued parameter the user must have EXECUTE permission on the type, or on the schema or database containing the type. Table-valued parameters have the following restrictions: SQL Server does not maintain statistics on columns of table-valued parameters.
Starting with SQL Server 2012 (11.x), table-valued parameters are also cached for parameterized queries. To create an instance of a User-Defined Table Type or call a stored procedure with a Table-valued parameter the user must have EXECUTE permission on the type, or on the schema or database containing the type.
There are several limitations to table-valued parameters: You cannot pass table-valued parameters to CLR user-defined functions. Table-valued parameters can only be indexed to support UNIQUE or PRIMARY KEY constraints. Table-valued parameters are read-only in Transact-SQL code.
I ended up doing this, Please note we are working on EF DataContext
(not ObjectContext
)
Executing a Stored procedure with output parameter
using (DataContext context = new DataContext())
{
////Create table value parameter
DataTable dt = new DataTable();
dt.Columns.Add("Displayname");
dt.Columns.Add("FirstName");
dt.Columns.Add("LastName");
dt.Columns.Add("TimeStamp");
DataRow dr = dt.NewRow();
dr["Displayname"] = "DisplayName";
dr["FirstName"] = "FirstName";
dr["LastName"] ="LastName";
dr["TimeStamp"] = "TimeStamp";
dt.Rows.Add(dr);
////Use DbType.Structured for TVP
var userdetails = new SqlParameter("UserDetails", SqlDbType.Structured);
userdetails.Value = dt;
userdetails.TypeName = "UserType";
////Parameter for SP output
var result = new SqlParameter("ResultList", SqlDbType.NVarChar, 4000);
result.Direction = ParameterDirection.Output;
context.Database.ExecuteSqlCommand("EXEC UserImport @UserDetails, @ResultList OUTPUT", userdetails, result);
return result == null ? string.Empty : result.Value.ToString();
}
My Table-Value-Parameter (UDT Table) script looks like this:
CREATE TYPE [dbo].[UserType] AS TABLE (
[DisplayName] NVARCHAR (256) NULL,
[FirstName] NVARCHAR (256) NULL,
[LastName] NVARCHAR (256) NULL,
[TimeStamp] DATETIME NULL
)
And my store procedure begins like
CREATE PROCEDURE UserImport
-- Add the parameters for the stored procedure here
@UserDetails UserType Readonly,
@ResultList NVARCHAR(MAX) output
AS
For Stored procedure without output
parameter we don't need any ouput parameter added/passed to SP.
Hope it helps some one.
Perhaps we could also consider the SqlQuery method:
[Invoke]
public SomeResultType GetResult(List<int> someIdList)
{
var idTbl = new DataTable();
idTbl.Columns.Add("Some_ID");
someIdList.ForEach(id => idTbl.Rows.Add(id));
var idParam = new SqlParamter("SomeParamName", SqlDbType.Structured);
idParam.TypeName = "SomeTBVType";
idParam.Value = idTbl;
// Return type will be IEnumerable<T>
var result = DbContext.Database.SqlQuery<SomeResultType>("EXEC SomeSPName, @SomeParamName", idParam);
// We can enumerate the result...
var enu = result.GetEnumerator();
if (!enu.MoveNext()) return null;
return enu.Current;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With