2009-01-31 8 views
15

J'ai une contrainte de clé étrangère entre les tables Sessions et les utilisateurs. Plus précisément, Sessions.UID = Users.ID. Parfois, je veux que Sessions.UID soit nul. Cela peut-il être autorisé? Chaque fois que j'essaie de faire cela, je reçois une violation de contrainte FK.SQL Server 2005: contrainte de clé étrangère Nullable

Spécifiquement, j'insère une ligne dans Sessions via LINQ. Je définis le Session.User = null; et je reçois cette erreur:

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.

Cependant, lorsque je retire la ligne qui NULLS la propriété de l'utilisateur, je reçois cette erreur sur ma ligne SubmitChanges:

Value cannot be null. 
Parameter name: cons

Aucun de mes tableaux ont un champ appelé « contre ', et ce n'est pas non plus dans mon fichier DataContext.designer.cs à 5 500 lignes, et ce n'est pas non plus dans le QuickWatch pour aucun des objets liés, donc je n'ai aucune idée de ce que' cons 'est.

Dans la base de données, Session.UID est un champ int nullable et User.ID est un int non nul. Je veux enregistrer des sessions qui peuvent ou non avoir un UID, et je préfère le faire sans désactiver la contrainte sur cette relation FK. Y a-t-il un moyen de faire cela?

Répondre

27

Je semblais me souvenir d'avoir créé un FK Nullable auparavant, alors j'ai lancé un test rapide. Comme vous pouvez le voir ci-dessous, c'est définitivement faisable (testé sur MSSQL 2005). Écrivez les parties pertinentes de vos tables et contraintes et publiez-les afin que nous puissions résoudre d'autres problèmes.

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

Droit adk. +1 La définition d'une clé étrangère est la suivante: il s'agit d'une valeur dans une table qui doit correspondre à une valeur de clé primaire dans une autre table ou être nulle. – Alan

+1

Logiquement, c'est logique, non? Je l'ai lu comme ceci: SI j'essaie de référencer un enregistrement dans une autre table, assurez-vous que la référence est valide. Si je ne le fais pas (NULL), on s'en fout. –