Passage d'une collection d'objects en tant que paramètre dans une procédure stockée SQL Server

J'ai une question générale à savoir si quelque chose peut être fait – et si ce sera la façon la plus efficace de le faire!

Pour résumer: puis-je transmettre une collection d'objects en tant que paramètre à une procédure stockée?

Disons que j'ai une table SQL Server appelée Users [UserID, Forename, Surname] et une autre table appelée Hobbies [HobbyID, UserID, HobbyName, HobbyTypeID]

Cette configuration consiste à save plusieurs passe-time contre un user.

Dans mon application, je veux mettre à jour l'logging de l'user.

Normalement, je voudrais mettre à jour la table des users, puis dans le code, faire une boucle dans chaque passe-time et mettre à jour l'logging de la table des loisirs par logging.

Si je mets à jour le nom de l'user et 2 de ses hobbies, cela nécessiterait 3 appels à la database.

(1 appel à une procédure stockée pour mettre à jour le prénom / nom, et 2 appels à une procédure stockée pour mettre à jour les 2 loggings hobby)

Ma question est:
Puis-je faire seulement 1 appel à la database en passant tous les parameters à seulement 1 procédure stockée.

par exemple.

 intUserID = 1 strForename = "Edward" strSurname = "ScissorHands" dim objHobbyCollection as New List(Of Hobby) 'Assume that I have 2 hobby objects, each with their hobbyID, UserID, HobbyName & HobbyTypeID Dim params As SqlParameter() params = New SqlParameter() { New SqlParameter("@UserID", intUserID), New SqlParameter("@Forename", strForename), New SqlParameter("@Surname", strSurname), New SqlParameter("@Hobbies", objHobbyCollection) } 

Puis-je faire ceci ? (et de quelle manière serait-il plus efficace?) À quoi ressemblerait la procédure stockée?

 ALTER PROCEDURE [dbo].[User_Update] @UserID INT ,@Forename NVARCHAR(50) = NULL ,@Surname NVARCHAR(50) = NULL ,@Hobbies ?????????????? 

En supposant SQL Server 2008+, vous pouvez le faire en utilisant un paramètre table. D'abord dans SQL Server, créez un type de table:

 CREATE TYPE dbo.HobbiesTVP AS TABLE ( HobbyID INT PRIMARY KEY, HobbyName NVARCHAR(50), HobbyTypeID INT ); 

Ensuite, votre procédure stockée dirait:

 @Hobbies dbo.HobbiesTVP READONLY 

En C # (désolé, je ne connais pas l'équivalent vb.net) ce serait comme suit (mais si vous avez juste un UserID, cela n'a pas besoin de faire partie de la collection, n'est-ce pas?):

 // as Steve pointed out, you may need to have your hobbies in a DataTable. DataTable HobbyDataTable = new DataTable(); HobbyDataTable.Columns.Add(new DataColumn("HobbyID")); HobbyDataTable.Columns.Add(new DataColumn("HobbyName")); HobbyDataTable.Columns.Add(new DataColumn("HobbyTypeID")); // loop through objHobbyCollection and add the values to the DataTable, // or just populate this DataTable in the first place using (connObject) { SqlCommand cmd = new SqlCommand("dbo.User_Update", connObject); cmd.CommandType = CommandType.StoredProcedure; // other params, eg @UserID SqlParameter tvparam = cmd.Parameters.AddWithValue("@Hobbies", HobbyDataTable); tvparam.SqlDbType = SqlDbType.Structured; // ...presumably ExecuteNonQuery() }