2009-01-31 11 views
15

Ho un vincolo di chiave esterna tra le tabelle Sessioni e Utenti. In particolare, Sessions.UID = Users.ID. A volte, desidero che Sessions.UID sia nullo. Questo può essere permesso? Ogni volta che provo a farlo, ottengo una violazione FK Constraint.SQL Server 2005: Nullable Foreign Key Constraint

In particolare, sto inserendo una riga in Sessioni tramite LINQ. Ho impostato Session.User = null; e ottengo questo errore:

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.

Tuttavia, quando rimuovo la linea che azzera la proprietà d'uso, ottengo questo errore sulla mia linea SubmitChanges:

Value cannot be null. 
Parameter name: cons

Nessuno dei miei tavoli hanno un campo chiamato 'cons ', né è nel mio file DataContext.designer.cs a 5.500 righe, né nel QuickWatch per nessuno degli oggetti correlati, quindi non ho idea di cosa sia' cons '.

Nel database, Session.UID è un campo int per il nullable e User.ID è un int non nullable. Voglio registrare sessioni che potrebbero avere o meno un UID, e preferirei farlo senza disabilitare il vincolo su quella relazione FK. C'è un modo per fare questo?

risposta

27

Mi è sembrato di ricordare di aver creato un FK Null in precedenza, quindi ho eseguito un rapido test. Come puoi vedere qui sotto, è sicuramente fattibile (testato su MSSQL 2005).

Script le parti pertinenti delle tabelle e dei vincoli e pubblicali in modo da consentirci di risolverli ulteriormente.

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

Right adk. +1 La definizione di una chiave esterna è che si tratta di un valore in una tabella che deve corrispondere a un valore di chiave primaria in un'altra tabella o essere nullo. – Alan

+1

Logicamente, ha senso, giusto? L'ho letto così: se provo a fare riferimento a un record in un'altra tabella, assicurati che il riferimento sia valido. Se non lo faccio (NULL), a chi importa. –