How to use a procedure with a user-defined table type in Entity Framework?
I have the EF with database-first approach, when I add a procedure with a user-defined table type columns it will not reflected in the EF will update the model.
And how can I pass the user-defined table parameter in EF with procedure?
My procedure :
Sample_Proce_Sp ( @TableTest @UserDefinedTable Readonly ) AS BEgin Select * from @TableTest END
In EF I have updated the model, will adding the stored procedure it shows the error like
The model was generated with warnings or errors.
Please see the Error List for more details. These issues must be fixed before running your application.
Loading metadata from the database took 00:00:03.1330217.
Generating the model took 00:00:01.9251464.
Successfully registered the assembly 'System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' in the Web.Config file.
Update Data Firstly, we create a procedure that updates the record. Now we create a table type variable and pass this variable to stored procedure as user-defined table type parameter. After execution of the stored procedure, let us check the data of Employee tables.
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.
EntityFrameworkExtras on Github looks promising.
From the Git hub Site:
DbContext context = new DbContext("ConnectionString");
var proc = new AddMemberStoredWithAddressesProcedure()
{
FirstName = "Michael",
LastName = "Bovis",
Age = 26,
Addresses = new List<Address>()
{
new Address() {Line1 = "16", Line2 = "The Lane", Postcode = "MA24WE"}
}
};
context.Database.ExecuteStoredProcedure(proc);
Where "AddMemberStoredWithAddressesProcedure" and "Address" are both defined with special attributes.
I got a chance to try it out..
CREATE TYPE [dbo].[UdtGuidList] AS TABLE(
[Guid] [uniqueidentifier] NULL
)
GO
CREATE PROCEDURE [dbo].[MyUdtSproc]
-- Add the parameters for the stored procedure here
(@GuidList UdtGuidList READONLY)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT *
from Blog b
INNER JOIN @GuidList gl ON gl.Guid = b.BlogGuid
--where b.BlogGuid in (SELECT gl.Guid from @GuidList gl)
END
It created this dynamic SQL with 5 rows of the custom type..
declare @p3 dbo.UdtGuidList
insert into @p3 values(N'333f3916-c823-e311-84f2-0022198ef787')
insert into @p3 values(N'33327a17-c34e-e211-9a8c-0022198ef787')
insert into @p3 values(N'333ebc24-c44e-e211-9a8c-0022198ef787')
insert into @p3 values(N'3338d557-c44e-e211-9a8c-0022198ef787')
insert into @p3 values(N'333d7f92-c44e-e211-9a8c-0022198ef787')
exec sp_executesql N'EXEC [dbo].[MyUdtSproc] @GuidList = @GuidList ',N'@GuidList [UdtGuidList] READONLY',@GuidList=@p3
This might get the work done, but the sql could grow large with many rows in the user defined table. I'm going to compare this to old ADO.
I tried the old DataTable ADO (below) and traced SQL to see what it produced. It was EXACTLY the same!
var dt = new DataTable();
dt.Columns.Add("Guid");
foreach (var r in list)
{
var row = dt.NewRow();
row["Guid"] = r.Guid;
dt.Rows.Add(row);
}
using (var conn = new SqlConnection(@"Server=AComputer\DEVSQL;Database=Booyaa;Trusted_Connection=True"))
{
using (var sproc = new SqlCommand("[dbo].[MyUdtSproc]", conn))
{
var param = new SqlParameter("@GuidList", SqlDbType.Structured);
param.TypeName = "[dbo].[UdtGuidList]";
param.SqlValue = dt;
sproc.Parameters.Add(param);
if (conn.State != ConnectionState.Open) conn.Open();
var reader = sproc.ExecuteReader();
}
}
Cool! I say this library is a valid option.
Update:
More information from my blog
A Sample Visual Studio Project
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