Tom Davis, Managing Consultant at Sogeti USA contributes the following blog entry for today.


Entity Framework (EF) doesn’t play well with table-valued parameters. Remember that these are an excellent way to call a process once, rather than over and over, to send data to SQL Server. While some looping action is occurring behind the scenes, on the outside it’s a clean way to send may rows to the database…one connection, one call, and one or more rows.  I’ve seen several workarounds on the internet for this problem, and here’s another one for your consideration. This one simply uses the nodes() Method and shreds an XML input. Pretty slick!

Example below. I’ve fixed some of the carriage returns because when I paste in live writer it extends off of the page, so copy and change to your liking. This POC includes a table to hold results, the parsing function, and a stored procedure that you would call from your EF app; note that you pass “untyped XML” to the stored procedure via varchar (max), and then handle the XML shredding later.

 

USE tempdb
GO
DROP TABLE XMLResults
GO
CREATE TABLE XMLResults
    (Rownumber INT NOT NULL PRIMARY KEY
    ,ID INT
    ,Lyric VARCHAR (1000)
    )
 
DROP FUNCTION [dbo].[ufnParseXML] 
GO
CREATE FUNCTION [dbo].[ufnParseXML] (@intput varchar(max))
RETURNS @XMLTable TABLE (Rownumber int,ID int,    Lyric varchar(150))
AS
BEGIN    
    DECLARE    @XML XML = CONVERT(xml,@intput)
    
    INSERT    @XMLTable (Rownumber,ID,Lyric)
    SELECT    T.c.value('Rownumber[1]','int') AS Rownumber,
            CASE WHEN T.c.value('ID[1]','int') = 0 THEN NULL ELSE T.c.value('ID[1]','int')
                   END AS ID,
            CASE WHEN ISNULL(T.c.value('Lyric[1]','varchar(150)'),'') = '' THEN NULL 
ELSE T.c.value('Lyric[1]','varchar(150)')
END AS Lyric
    FROM    @XML.nodes('root/row') AS T(c)
    
    RETURN
END
GO
 
DROP PROCEDURE dbo.usp_InsertData
go
CREATE PROCEDURE dbo.usp_InsertData (@input VARCHAR(MAX), @ErrorMessage NVARCHAR(1000) OUTPUT)
AS
SET NOCOUNT ON
BEGIN TRY
 
    INSERT INTO XMLResults (Rownumber, ID, Lyric)
    SELECT Rownumber, ID, Lyric FROM dbo.ufnParseXML(@input)
 
END TRY
 
BEGIN CATCH
    SELECT    @ErrorMessage = 'Error Message: ' + ISNULL(ERROR_MESSAGE(),'') +
                        ', Error number: ' + ISNULL(CONVERT(varchar(30),ERROR_NUMBER()),'') +
                        ', Error severity: ' + ISNULL(CONVERT(varchar(30),ERROR_SEVERITY()),'')+ 
                        ', Error Procedure: ' + ISNULL(ERROR_PROCEDURE(),'') +
                        ', Error Line: ' + ISNULL(CONVERT(varchar(30),ERROR_LINE()),'')
 
    RAISERROR(@ErrorMessage,16,1)
END CATCH
GO
 
DECLARE @ERR NVARCHAR(1000) = ''
 
EXEC dbo.usp_InsertData @input='<root>
                <row><Rownumber>1</Rownumber><ID>100</ID><Lyric>Not need, just feed the war cann
                          ibal animal</Lyric></row>
                <row><Rownumber>2</Rownumber><ID>200</ID><Lyric>Solo, I"m a soloist on a solo
list, ah live never on a floppy disk</Lyric></row>
                <row><Rownumber>3</Rownumber><ID>300</ID><Lyric>Rally round tha family with 
                  a pocket full of shells</Lyric>
                </row>
            </root>'
            ,@errormessage=@ERR OUTPUT
SELECT Rownumber, ID, Lyric
FROM XMLResults
 
 
Results

 

 

Very nice! Tom has implemented this in a production environment with favorable results, and recommends this approach as a substitute for TVPs when using an ORM tool such as EF.

Thanks for reading,

Lee Everest

 

------------------------------

 

 

http://msdn.microsoft.com/en-us/library/ms188282.aspx


Posted in: .Net , SQL Server 2008/R2  Tags:
blog comments powered by Disqus

by Lee Everest, M.S.

Info

Poll

Do you use Azure or cloud in your organization?



Show Results

Ads

Search


Month List

Calendar

«  May 2012  »
MoTuWeThFrSaSu
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910
View posts in large calendar

Tags

Disclaimer
The opinions, code, examples, et.al. expressed herein are my own personal opinions and do not represent my employer's view in any way, shape form, or fashion.  All code for demonstration purposes - no guarantees, either written or implied, are made.

© Copyright 2012 Lee Everest's SQL Server, etc. weblog