实现可选关系(如果 FK 不为空则强制执行)
假设我们有这些表
Person( person_id, name, car_id )
CompanyCar( car_id, make, model, colour, plate )
Person.car_id 应该是 CompanyCar.car_id 的外键,但我希望 Person.car_id 可以为空,所以当我运行 sqlmetal 生成 linq-to-sql DataContext 时,我应该得到
class Person{
int person_id,
string name,
int? car_id,
CompanyCar companyCar //object references may hold null
}
并且 如果存在,Person.car_id 应该存在于 CompanyCar 中。
根据我读过的 MSDN 文档,这应该是不可能的,但是当我们尝试时,它起作用了。似乎很少有人在网上写或询问这种类型的关系。
我可以相信这个外键是强制执行的,同时也是可选的吗?
更新: 以下是当我请求 CREATE 脚本时 SMSS 生成的内容。请注意,FK 创建为 NOCHECK 但是,如果我输入我知道 CompanyCar 表中不存在的 CarID(例如 9999),它确实会抱怨。
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Person](
[PersonID] [int] NOT NULL,
[Name] [varchar](100) NOT NULL,
[CarID] [int] NULL
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED
(
[PersonID] ASC
)WITH FILLFACTOR = 92 ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Person] WITH NOCHECK ADD CONSTRAINT [FK_Person_CompanyCar] FOREIGN KEY([CarID])
REFERENCES [dbo].[CompanyCar] ([CarID])
GO
(对名称不一致表示歉意,工作需要示例命名)
Suppose we have these tables
Person( person_id, name, car_id )
CompanyCar( car_id, make, model, colour, plate )
Person.car_id should be a foreign key to CompanyCar.car_id, but I want Person.car_id to be nullable, so when I run sqlmetal to generate a linq-to-sql DataContext, I should get
class Person{
int person_id,
string name,
int? car_id,
CompanyCar companyCar //object references may hold null
}
and if present, Person.car_id should exist in CompanyCar.
According to the MSDN documentation I've read, this shouldn't be possible, but when we tried it, it worked. Few people seem to write or ask about this type of relationship online.
Can I trust this foreign key to be enforced whilst also being optional?
UPDATE:
Here is what SMSS generated when I asked for a CREATE script. Note the FK is created as NOCHECK but it does complain if I enter a CarID (e.g. 9999) which I know doesn't exist in the CompanyCar table.
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Person](
[PersonID] [int] NOT NULL,
[Name] [varchar](100) NOT NULL,
[CarID] [int] NULL
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED
(
[PersonID] ASC
)WITH FILLFACTOR = 92 ON [PRIMARY]
) ON [PRIMARY]
GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[Person] WITH NOCHECK ADD CONSTRAINT [FK_Person_CompanyCar] FOREIGN KEY([CarID])
REFERENCES [dbo].[CompanyCar] ([CarID])
GO
(Apologies for name inconsistencies, job requires example naming)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
可空列上的 FK 引用完全按照您的希望工作。当存在非 NULL 值时,通常会强制执行 FK 约束。 FK 约束不会检查 NULL 值,因为该值当前未知,无法判断它是否违反约束。
A FK reference on a nullable column works exactly as you're hoping. When a non-NULL value is present, the FK constraint is enforced normally. A NULL value is not checked by the FK constraint, as the value is currently unknown and it's impossible to say whether or not it violates the constraint.