Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use the Procedure with User Defined Table Type in Entity Framework

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. 
like image 525
vksravanan Avatar asked Jan 07 '14 12:01

vksravanan


People also ask

How can use user-defined table type in stored procedure?

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.

How do you call a table valued function in Entity Framework?

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.


1 Answers

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

like image 194
TheDev6 Avatar answered Sep 23 '22 23:09

TheDev6