2014-01-07 4 views
4

Как использовать процедуру с определенным пользователем типом таблицы в 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. 

ответ

7

EntityFrameworkExtras on 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" и "Адрес" оба определены специальными атрибутами.

Я получил шанс попробовать его ..

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',@[email protected] 

Это может сделано работа, но sql может увеличиться с большим количеством строк в пользовательской таблице. Я собираюсь сравнить это со старым ADO.

Я попробовал старый ADT (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(); 
     } 
    } 

Прохладный! Я говорю, что эта библиотека является допустимым вариантом.

Update:

More information from my blog

A Sample Visual Studio Project

Смежные вопросы