SQL Server 2005:可以为空的外键约束

时间:2009-01-31 21:48:45

标签: sql linq linq-to-sql constraints foreign-keys

我在表Sessions和Users之间有一个外键约束。具体来说,Sessions.UID = Users.ID。有时,我希望Sessions.UID为null。这可以允许吗?每当我尝试这样做时,我都会受到FK约束违规。

具体来说,我是通过LINQ在Sessions中插入一行。我设置Session.User = null;我收到此错误:

An attempt was made to remove a relationship between a User and a Session. However, one of the relationship's foreign keys (Session.UID) cannot be set to null.

但是,当我删除使User属性为空的行时,我在SubmitChanges行上收到此错误:

Value cannot be null.
Parameter name: cons

我的表中没有一个名为'cons'的字段,也不在我的5,500行DataContext.designer.cs文件中,也没有在任何相关对象的QuickWatch中,所以我不知道是什么'缺点是。

在数据库中,Session.UID是一个可以为空的int字段,User.ID是一个不可为空的int。我想记录可能有或没有UID的会话,而我宁愿这样做而不禁用该FK关系的约束。有没有办法做到这一点?

1 个答案:

答案 0 :(得分:27)

我似乎记得之前创建了一个可以为空的FK,所以我开始快速测试。正如您在下面看到的,它绝对可行(在MSSQL 2005上测试)。

编写表格和约束的相关部分并发布它们,以便我们进一步排除故障。

CREATE DATABASE [NullableFKTest]
GO
USE [NullableFKTest]
GO
CREATE TABLE OneTable 
(
    OneId  [int] NOT NULL,
    CONSTRAINT [PK_OneTable] PRIMARY KEY CLUSTERED 
    (
        [OneId] ASC
    )
)
CREATE TABLE ManyTable (ManyId  [int] IDENTITY(1,1) NOT NULL, OneId [int] NULL)
GO
IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_ManyTable_OneTable]') AND parent_object_id = OBJECT_ID(N'[dbo].[ManyTable]') )
ALTER TABLE [dbo].[ManyTable]  WITH CHECK ADD CONSTRAINT [FK_ManyTable_OneTable] FOREIGN KEY([OneId])
    REFERENCES [dbo].[OneTable] ([OneId])   
GO

--let's get a value in here
insert into OneTable(OneId) values(1)
select* from OneTable

--let's try creating a valid relationship to the FK table OneTable
insert into ManyTable(OneId) values (1) --fine
--now, let's try NULL
insert into ManyTable(OneId) values (NULL) --also fine
--how about a non-existent OneTable entry?
insert into ManyTable(OneId) values (5) --BOOM! - FK violation

select* from ManyTable
--1, 1
--2, NULL

--cleanup
ALTER TABLE ManyTable DROP CONSTRAINT FK_ManyTable_OneTable
GO
drop TABLE OneTable
GO
drop TABLE ManyTable
GO
USE [Master]
GO
DROP DATABASE NullableFKTest