SubSonic 2.x now supports TVP's - SqlDbType.Structure / DataTables for SQL Server 2008

Posted by ElHaix on Stack Overflow See other posts from Stack Overflow or by ElHaix
Published on 2010-06-08T17:07:57Z Indexed on 2010/06/08 17:12 UTC
Read the original article Hit count: 550

For those interested, I have now modified the SubSonic 2.x code to recognize and support DataTable parameter types.

You can read more about SQL Server 2008 features here: http://download.microsoft.com/download/4/9/0/4906f81b-eb1a-49c3-bb05-ff3bcbb5d5ae/SQL%20SERVER%202008-RDBMS/T-SQL%20Enhancements%20with%20SQL%20Server%202008%20-%20Praveen%20Srivatsav.pdf

What this enhancement will now allow you to do is to create a partial StoredProcedures.cs class, with a method that overrides the stored procedure wrapper method.

A bit about good form: My DAL has no direct table access, and my DB only has execute permissions for that user to my sprocs. As such, SubSonic only generates the AllStructs and StoredProcedures classes.

The SPROC:

ALTER PROCEDURE [dbo].[testInsertToTestTVP]
@UserDetails TestTVP READONLY,
@Result INT OUT

AS BEGIN SET NOCOUNT ON;

SET @Result = -1

--SET IDENTITY_INSERT [dbo].[tbl_TestTVP] ON

INSERT INTO [dbo].[tbl_TestTVP]
        ( [GroupInsertID], [FirstName], [LastName] )
SELECT [GroupInsertID], [FirstName], [LastName]
FROM @UserDetails

IF @@ROWCOUNT > 0
    BEGIN
        SET @Result = 1
        SELECT @Result
        RETURN @Result
    END
--SET IDENTITY_INSERT [dbo].[tbl_TestTVP] OFF

END

The TVP:

CREATE TYPE [dbo].[TestTVP] AS TABLE(
[GroupInsertID] [varchar](50) NOT NULL,
[FirstName] [varchar](50) NOT NULL,
[LastName] [varchar](50) NOT NULL

) GO

The the auto gen tool runs, it creates the following erroneous method:

    /// <summary>
    /// Creates an object wrapper for the testInsertToTestTVP Procedure
    /// </summary>
    public static StoredProcedure TestInsertToTestTVP(string UserDetails, int? Result)
    {
        SubSonic.StoredProcedure sp = new SubSonic.StoredProcedure("testInsertToTestTVP", DataService.GetInstance("MyDAL"), "dbo");     
        sp.Command.AddParameter("@UserDetails", UserDetails, DbType.AnsiString, null, null);
        sp.Command.AddOutputParameter("@Result", DbType.Int32, 0, 10);            
        return sp;
    }

It sets UserDetails as type string.

As it's good form to have two folders for a SubSonic DAL - Custom and Generated, I created a StoredProcedures.cs partial class in Custom that looks like this:

        /// <summary>
    /// Creates an object wrapper for the testInsertToTestTVP Procedure
    /// </summary>
    public static StoredProcedure TestInsertToTestTVP(DataTable dt, int? Result)
    {
        DataSet ds = new DataSet();


        SubSonic.StoredProcedure sp = new SubSonic.StoredProcedure("testInsertToTestTVP", 
                                                                    DataService.GetInstance("MyDAL"), 
                                                                    "dbo");

        // TODO: Modify the SubSonic code base in sp.Command.AddParameter to accept
        //       a parameter type of System.Data.SqlDbType.Structured, as it currently only accepts
        //       System.Data.DbType.
        //sp.Command.AddParameter("@UserDetails", dt, System.Data.SqlDbType.Structured null, null);

        sp.Command.AddParameter("@UserDetails", dt, SqlDbType.Structured);
        sp.Command.AddOutputParameter("@Result", DbType.Int32, 0, 10);

        return sp;
    }

As you can see, the method signature now contains a DataTable, and with my modification to the SubSonic framework, this now works perfectly.

I'm wondering if the SubSonic guys can modify the auto-gen to recognize a TVP in a sproc signature, as to avoid having to re-write the warpper?

Does SubSonic 3.x support Structured data types?

Also, I'm sure many will be interested in using this code, so where can I upload the new code?

Thanks.

© Stack Overflow or respective owner

Related posts about sql-server-2008

Related posts about subsonic