【问题标题】:How can I Insert/Update into two related tables in one command?如何在一个命令中插入/更新两个相关表?
【发布时间】:2011-03-21 16:48:00
【问题描述】:
一个数据库存在两个表
- Data_t:DataID 主键是
身份 1,1。还有另一个领域
'LEFT' TINYINT
- Data_Link_t:DataID PK 和 FK,其中
DataID 必须存在于 Data_t 中。还有另一个字段 'RIGHT' SMALLINT
从 microsoft 访问环境到 C# 和 sql server 我正在寻找一种将记录导入此关系的好方法。
记录包含属于此连接双方的信息(可能一次插入/更新超过 5000 条记录)。在某种 LINQ 列表类型命令中处理整个批次的好处,但即使这是逐条记录完成,关键目标是该记录的双方都应该在同一步骤中处理。
有无数种方法,我正在寻找太多的方法来确定我应该走哪条路,所以我想更快地询问公众。 LINQ 是使用 LINQ to SQL 插入/更新这样的大列表的选项吗?我应该逐条记录吗?我应该使用什么方法将记录添加到规范化表中,在加入时会创建完整记录?
【问题讨论】:
标签:
c#
sql-server
database-design
normalization
【解决方案1】:
听起来像是我要编写一个小型存储过程并从 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)。
【解决方案2】:
我自己从未尝试过,但您可以通过创建可更新的视图然后将记录插入到视图中来完全满足您的要求。
更新
我刚试了一下,好像不行。
消息 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)