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

14,966

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

Share:
14,966
Admin
Author by

Admin

Updated on June 12, 2022

Comments

  • Admin
    Admin over 1 year

    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.