Передача списка настраиваемого объекта в хранимую процедуру SQL Server

Я хочу передать список пользовательских объектов только с одним вызовом хранимой процедуры. Вот объект

public class OGFormResponse { public string Response {get; set;} public OGFormLabelVO FormLabel {get; set;} } public class OGFormLabelVO { public int OGFormLabelKey {get; set;} public string FormType {get; set;} public string LabelText {get; set;} public string ControlName {get; set;} public string DisplayStatus {get; set;} public string LabelType = {get; set;} public bool IsActive {get; set;} public string LabelParentControlName {get; set;} } 

Вот связь с базой данных

 CREATE TABLE [dbo].[OGFormLabels]( [OGFormLabelKey] [int] IDENTITY(1,1) NOT NULL, [OGFLText] [nvarchar](max) NULL, [OGFLControlName] [nvarchar](50) NOT NULL, [OGFLIsActive] [bit] NOT NULL, [OGFLDisplayStatusKey] [int] NOT NULL, [OGFLFormTypeKey] [int] NOT NULL, [OGFLLabelTypeKey] [int] NOT NULL, [OGFLParentKey] [int] NULL, [OGFLBeginDate] [datetime] NOT NULL, [OGFLBeginUser] [varchar](40) NOT NULL, [OGFLUpdateDate] [datetime] NOT NULL, [OGFLUpdateUser] [varchar](40) NOT NULL, CONSTRAINT [PK_OGFormLabel] PRIMARY KEY CLUSTERED ( [OGFormLabelKey] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [dbo].[OGFormLabels] ADD CONSTRAINT [DF_OGFormLabel_OGFLBeginDate] DEFAULT (getdate()) FOR [OGFLBeginDate] GO ALTER TABLE [dbo].[OGFormLabels] ADD CONSTRAINT [DF_OGFormLabel_OGFLBeginUser] DEFAULT ('dbo') FOR [OGFLBeginUser] GO ALTER TABLE [dbo].[OGFormLabels] ADD CONSTRAINT [DF_OGFormLabel_OGFLUpdateDate] DEFAULT (getdate()) FOR [OGFLUpdateDate] GO ALTER TABLE [dbo].[OGFormLabels] ADD CONSTRAINT [DF_OGFormLabel_OGFLUpdateUser] DEFAULT ('dbo') FOR [OGFLUpdateUser] GO ALTER TABLE [dbo].[OGFormLabels] WITH CHECK ADD CONSTRAINT [FK_OGFormLabel_OGFormStatus] FOREIGN KEY([OGFLFormTypeKey]) REFERENCES [dbo].[OGDisplayStatus] ([OGDisplayStatusKey]) GO ALTER TABLE [dbo].[OGFormLabels] CHECK CONSTRAINT [FK_OGFormLabel_OGFormStatus] GO ALTER TABLE [dbo].[OGFormLabels] WITH CHECK ADD CONSTRAINT [FK_OGFormLabel_OGFormType] FOREIGN KEY([OGFLFormTypeKey]) REFERENCES [dbo].[OGFormType] ([OGFormTypeKey]) GO ALTER TABLE [dbo].[OGFormLabels] CHECK CONSTRAINT [FK_OGFormLabel_OGFormType] GO ALTER TABLE [dbo].[OGFormLabels] WITH CHECK ADD CONSTRAINT [FK_OGFormLabel_OGLabelType] FOREIGN KEY([OGFLLabelTypeKey]) REFERENCES [dbo].[OGLabelType] ([OGLabelTypeKey]) GO ALTER TABLE [dbo].[OGFormLabels] CHECK CONSTRAINT [FK_OGFormLabel_OGLabelType] GO CREATE TABLE [dbo].[OGFormResponses]( [OGFormResponseKey] [int] IDENTITY(1,1) NOT NULL, [OGRFormKey] [int] NOT NULL, [OGRFormLabelKey] [int] NOT NULL, [OGRResponse] [nvarchar](max) NOT NULL, [OGRBeginDate] [datetime] NOT NULL, [OGRBeginUser] [varchar](40) NOT NULL, [OGRUpdateDate] [datetime] NOT NULL, [OGRUpdateUser] [varchar](40) NOT NULL, CONSTRAINT [PK_OGFormResponse] PRIMARY KEY CLUSTERED ( [OGFormResponseKey] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO SET ANSI_PADDING OFF GO ALTER TABLE [dbo].[OGFormResponses] ADD CONSTRAINT [DF_OGFormResponse_OGRBeginDate] DEFAULT (getdate()) FOR [OGRBeginDate] GO ALTER TABLE [dbo].[OGFormResponses] ADD CONSTRAINT [DF_OGFormResponse_OGRBeginUser] DEFAULT ('dbo') FOR [OGRBeginUser] GO ALTER TABLE [dbo].[OGFormResponses] ADD CONSTRAINT [DF_OGFormResponse_OGRUpdateDate] DEFAULT (getdate()) FOR [OGRUpdateDate] GO ALTER TABLE [dbo].[OGFormResponses] ADD CONSTRAINT [DF_OGFormResponse_OGRUpdateUser] DEFAULT ('dbo') FOR [OGRUpdateUser] GO ALTER TABLE [dbo].[OGFormResponses] WITH CHECK ADD CONSTRAINT [FK_OGFormResponse_OGForm] FOREIGN KEY([OGRFormKey]) REFERENCES [dbo].[OGForm] ([OGFormKey]) GO ALTER TABLE [dbo].[OGFormResponses] CHECK CONSTRAINT [FK_OGFormResponse_OGForm] GO ALTER TABLE [dbo].[OGFormResponses] WITH CHECK ADD CONSTRAINT [FK_OGFormResponse_OGFormLabel] FOREIGN KEY([OGRFormLabelKey]) REFERENCES [dbo].[OGFormLabels] ([OGFormLabelKey]) GO ALTER TABLE [dbo].[OGFormResponses] CHECK CONSTRAINT [FK_OGFormResponse_OGFormLabel] GO 

Таким образом, OGFormResponseVO имеет отношения 1 к 1 с OGFormLabelVO. Я хочу, чтобы вставить список OGFormResponseVO в базу данных через вызов Хранимой процедуры. Я просмотрел параметры таблицы и вы не можете иметь Колонку Тип – другой тип. Есть ли обходной путь для этого, или мне лучше просто передать все свойства дочернего объекта в виде отдельных параметров, или есть лучший способ. Я должен использовать SP, поскольку он является частью более крупного проекта, поэтому другие параметры модели данных недоступны.

Как я уже сказал в комментариях, вы можете сделать это со структурированными параметрами .

Вам просто нужно немного перемотать модель, чтобы вы могли сопоставить их с табличными параметрами (которые начинаются как DataTable s).

Предполагая, что вы хотите вставить как ярлыки форм, так и связанные ответы в один и тот же путь, вам необходимо определить временные отношения между ними. Кроме того, заметили, что в таблицах больше столбцов, чем у моделей, поэтому я думаю, что вы уменьшили исходный пример.

Структурированный параметр, соответствующий классу OGFormResponse должен иметь следующие поля:

 CREATE TYPE [dbo].[OGFormResponse] AS TABLE( [Response] VARCHAR(256), [SequenceId] INT --This is just a temporary sequence (1..N) you can use to map to form labels (see below) ) 

OGFormLabelVO тип для OGFormLabelVO может быть сопоставлен 1: 1 с классом C # плюс один дополнительный столбец – SequenceId .

SP может выглядеть примерно так:

 CREATE PROCEDURE [dbo].[SaveFormStuff] @FormResponses AS [dbo].[OGFormResponse] READONLY, @FormLabels AS [dbo].[OGFormLabelVO] READONLY AS SET NOCOUNT ON; //This stores the PKs of the inserted form labels DECLARE @InsertedFormLabels AS TABLE ( Id INT NOT NULL, SequenceId INT NOT NULL ) INSERT INTO [dbo].[OGFormLabels] (...) SELECT (...) FROM @FormLabels FL OUTPUT inserted.OGFormLabelKey, FL.SequenceId INTO @InsertedFormLabels -- Now you have the newly inserted form label ID mapped to sequence IDs -- Time to insert responses INSERT INTO [dbo].[OGFormResponses] (...) SELECT (...), OGRFormLabelKey = IFL.Id FROM @FormResponses FR INNER JOIN @InsertedFormLabels IFL ON IFL.SequenceId = FR.SequenceId END 
  • с помощью Dynamic SQL - пользовательская универсальная многопользовательская хранимая процедура (с TVPar)
  • Таблица-параметр в хранимой процедуре и платформа Entity Framework 4.0
  • Параметр значения таблицы из c #
  • Передача параметра типа «объект» в параметре table-valued для столбца sql_variant
  • Вызов методов хранения с параметром значения таблицы в Entity Framework 6.0
  • Давайте будем гением компьютера.