Как да използвате процедурата с дефиниран от потребителя тип таблица в Entity Framework

Как да използвам процедура с дефиниран от потребителя тип таблица в Entity Framework?

Имам EF с първи подход към базата данни, когато добавя процедура с дефинирани от потребителя колони от тип таблица, тя няма да се отрази в EF, ще актуализира модела.

И как мога да предам дефинирания от потребителя параметър на таблица в EF с процедура?

Моята процедура:

Sample_Proce_Sp ( @TableTest @UserDefinedTable Readonly) AS BEgin Изберете * от @TableTest END

В EF актуализирах модела, ще добавя съхранената процедура, която показва грешката като

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. 

person vksravanan    schedule 07.01.2014    source източник


Отговори (1)


EntityFrameworkExtras в Github изглежда обещаващо.

От сайта на Git hub:

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);

Където „AddMemberStoredWithAddressesProcedure“ и „Address“ са дефинирани със специални атрибути.

Имах възможност да го пробвам..

    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

Той създаде този динамичен SQL с 5 реда от потребителски тип..

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

Това може да свърши работата, но sql може да стане голям с много редове в дефинираната от потребителя таблица. Ще сравня това със стария ADO.

Опитах стария DataTable ADO (по-долу) и проследих SQL, за да видя какво произвежда. Беше ТОЧНО същото!

   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();
        }
    }

Готино! Казвам, че тази библиотека е валидна опция.

Актуализация:

Повече информация от моя блог

Примерен проект на Visual Studio

person TheDev6    schedule 14.01.2014