Как использовать процедуру с пользовательским типом таблицы в Entity Framework

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

У меня есть EF с подходом, ориентированным на базу данных, когда я добавляю процедуру со столбцами пользовательского типа таблицы, она не будет отражаться в EF, которая будет обновлять модель.

И как я могу передать пользовательский параметр таблицы в EF с помощью процедуры?

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

Sample_Proce_Sp ( @TableTest @UserDefinedTable Только для чтения ) AS BEgin Select * from @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:

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