2009-01-31 45 views
15

Tôi có một ràng buộc khóa ngoài giữa các phiên Sessions và Users. Cụ thể, Sessions.UID = Users.ID. Đôi khi, tôi muốn Sessions.UID là null. Điều này có được phép không? Bất cứ lúc nào tôi cố gắng làm điều này, tôi đều nhận được một vi phạm về ràng buộc FK.SQL Server 2005: Nullable Foreign Key Constraint

Cụ thể, tôi sẽ chèn một hàng vào Phiên qua LINQ. Tôi đặt Session.User = null; và tôi nhận được lỗi này:

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.

Tuy nhiên, khi tôi loại bỏ các dòng null tài sản tài, tôi nhận được lỗi này trên SubmitChanges dòng của tôi:

Value cannot be null. 
Parameter name: cons

Không ai trong số bảng của tôi đã một lĩnh vực được gọi là 'khuyết điểm ', cũng không phải trong tệp DataContext.designer.cs 5,500 dòng của tôi, cũng không phải trong QuickWatch cho bất kỳ đối tượng liên quan nào, vì vậy tôi không có ý tưởng' nhược điểm 'là gì.

Trong cơ sở dữ liệu, Session.UID là trường int có thể vô hiệu và User.ID là một int không thể null. Tôi muốn ghi lại các phiên có thể có hoặc không có UID và tôi muốn thực hiện nó mà không vô hiệu hóa ràng buộc về mối quan hệ FK đó. Có cách nào để làm việc này không?

Trả lời

27

Tôi dường như đã nhớ việc tạo một FK vô hiệu trước đây, vì vậy tôi đã thực hiện một bài kiểm tra nhanh. Như bạn thấy dưới đây, nó chắc chắn là có thể thực hiện được (được thử nghiệm trên MSSQL 2005).

Viết các phần có liên quan của bảng và các ràng buộc của bạn và đăng chúng để chúng tôi có thể khắc phục sự cố thêm.

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 
+7

Đúng adk. +1 Định nghĩa của khóa ngoài là giá trị trong một bảng phải khớp với giá trị khóa chính trong bảng khác hoặc là rỗng. – Alan

+1

Về mặt logic, nó có ý nghĩa, đúng không? Tôi đọc nó như thế này: NẾU tôi cố gắng tham khảo một bản ghi trong bảng khác, hãy chắc chắn rằng tham chiếu là hợp lệ. Nếu tôi không (NULL), ai quan tâm. –

Các vấn đề liên quan