Как я могу вставить / обновить в две связанные таблицы в одной команде? - PullRequest
0 голосов
/ 27 июля 2010

База данных существует с двумя таблицами

  • Data_t: первичный ключ DataID, который является Identity 1,1.Также имеется другое поле 'LEFT' TINYINT
  • Data_Link_t: DataID PK и FK, где DataID ДОЛЖЕН существовать в Data_t.Также есть другое поле 'ПРАВО' SMALLINT

Исходя из среды доступа Microsoft в C # и SQL Server, я ищу хороший способ импорта записи в это отношение.

Запись содержит информацию, которая принадлежит обеим сторонам этого объединения (возможно вставка / обновление более 5000 записей одновременно).Бонус для обработки всего пакета в какой-то команде типа списка LINQ, но даже если это делается запись за записью, ключевой целью является то, что ОБА стороны этой записи должны обрабатываться на одном шаге.

Существует бесчисленное множествоподходы, и я смотрю на слишком многих, чтобы определить, в каком направлении мне идти, поэтому я решил быстрее спросить широкую публику.Является ли LINQ возможностью вставки / обновления большого списка, подобного этому, с помощью LINQ to SQL?Должен ли я пойти запись за записью?Какой подход я должен использовать для добавления записи в нормализованные таблицы, которые при объединении создают полную запись?

Ответы [ 2 ]

2 голосов
/ 27 июля 2010

Похоже на случай, когда я написал бы небольшой сохраненный процесс и вызвал бы его из C # - например, как функцию в моем объекте контекста данных Linq-to-SQL.

Что-то вроде:

CREATE PROCEDURE dbo.InsertData(@Left TINYINT, @Right SMALLINT)
AS BEGIN
   DECLARE @DataID INT

   INSERT INTO dbo.Data_t(Left) VALUES(@Left)

   SELECT @DataID = SCOPE_IDENTITY();

   INSERT INTO dbo.Data_Link_T(DataID, Right) VALUES(@DataID, @Right)
END

Если вы импортируете это в свой контекст данных, вы можете назвать это примерно так:

using(YourDataContext ctx = new YourDataContext)
{
   foreach(YourObjectType obj in YourListOfObjects)
   {
      ctx.InsertData(obj.Left, obj.Right)
   }
}

и позволить сохраненному процессу обрабатывать все остальное (все детали, например, определение и использование IDENTITY).из первой таблицы во второй) для вас.

0 голосов
/ 27 июля 2010

Я никогда не пробовал сам, но вы могли бы сделать именно то, что вы просите, создав обновляемое представление и затем вставляя записи в представление.

UPDATE

Я только что попробовал, и не похоже, что это будет работать.

Сообщение 4405, уровень 16, состояние 1, строка 1 Представление или функция Data_t_and_Data_Link_t не могут быть обновлены, так как модификация затрагивает несколько базовых таблиц.

Я полагаю, что это еще одна вещь, которую все пуристы теории реляционных баз данных ненавидят в SQL Server.

ДРУГОЕ ОБНОВЛЕНИЕ

Дальнейшие исследования нашли способ сделать это. Это можно сделать с помощью представления и триггера «вместо».

create table Data_t 
(
    DataID int not null identity primary key,
    [LEFT] tinyint,
)
GO

create table Data_Link_t 
(
    DataID int not null primary key foreign key references Data_T (DataID),
    [RIGHT] smallint,
)
GO

create view Data_t_and_Data_Link_t 
as
select
    d.DataID,
    d.[LEFT],
    dl.[RIGHT]
from
    Data_t d
    inner join Data_Link_t dl on dl.DataID = d.DataID 
GO

create trigger trgInsData_t_and_Data_Link_t on Data_t_and_Data_Link_T
instead of insert
as
insert into Data_t ([LEFT]) select [LEFT] from inserted 
insert into Data_Link_t (DataID, [RIGHT]) select @@IDENTITY, [RIGHT] from inserted
go

insert into Data_t_and_Data_Link_t ([LEFT],[RIGHT]) values (1, 2)
...