防止在C#或SQL中插入或更新数据

防止在C#或SQL中插入或更新数据,c#,sql,linq,C#,Sql,Linq,我有两个表头和表项,它们有一对多的关系 标题表 Id StartDate EndDate --------------------------------------- 1 1999/1/1 1999/5/1 2 2000/1/1 2000/4/1 3 2000/1/1 2000/5/1 和项目表 Id HeaderRef SLRef -----------------------------

我有两个表头和表项,它们有一对多的关系

标题表

Id      StartDate   EndDate 
--------------------------------------- 
1       1999/1/1    1999/5/1        
2       2000/1/1    2000/4/1
3       2000/1/1    2000/5/1
和项目表

Id      HeaderRef   SLRef
-------------------------------------
101     1           201
102     2           201

如何防止添加带有
HeaderRef=3
SLRef=201
的项目,因为它具有相同的
SLRef
,而
HeaderRef
引用它的标题行有
StartDate和EndDate
,另一个具有相同
SLRef
的项目引用了该范围内的
标题。

假设您使用的是MS SQL Server,有两种方法可以实现您想要的目标:

1) 按照其他用户的建议使用触发器。触发器将用于INSERT/UPDATE,它将检查日期范围,并允许添加新值或引发错误

2) 您可以在ItemTable中使用复合主键:

CREATE TABLE [dbo].[ItemTable](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [HeaderRef] [int] NOT NULL,
    [SLRef] [int] NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [HeaderRef] ASC,
    [SLRef] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
现在,这将在ItemTable上设置一个约束,sql server将不允许重复组合headerRef和SLRef int值(键)

返回HeaderTable,可以设置唯一约束以停止复制开始日期和结束日期的范围

CREATE TABLE [dbo].[HeaderTable](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [STARTDATE] [datetime] not NULL,
    [ENDDATE] [datetime] not NULL,
 CONSTRAINT [PK_HeaderTable] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
现在在HeaderTable上为开始日期和结束日期创建唯一索引

/****** Object:  Index [IX_HeaderTable]    Script Date: 03/13/2017 12:24:51 ******/
CREATE UNIQUE NONCLUSTERED INDEX [IX_HeaderTable] ON [dbo].[HeaderTable] 
(
    [ENDDATE] ASC,
    [STARTDATE] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO
您还可以对HeaderTable设置另一个约束,该约束将检查开始日期是否不能早于结束日期

ALTER TABLE [dbo].[HeaderTable]  WITH CHECK ADD  CONSTRAINT [CheckEndLaterThanStart] CHECK  (([ENDDATE]>=[STARTDATE]))
GO

ALTER TABLE [dbo].[HeaderTable] CHECK CONSTRAINT [CheckEndLaterThanStart]
GO

希望这有帮助

您正在寻找DML触发器,简单地说,它是一种sql函数或过程,当用户试图通过添加或删除来更改数据库中的数据时,会自动调用该函数或过程,此外,触发器的主体可以包含一些验证逻辑,因此除非满足特定条件,否则不会插入数据

是否尝试插入/更新触发器?你可以写一些。你想在ItemTable中保持headerRef和SLRef唯一吗?是的,我想在添加到Hedar的日期范围中保持headerRef和SLRef唯一。类似这样的内容:isValid=!(Headers.Any(x=>(Header.StartDate=x.StartDate));