2009-01-31 22 views
15

Tengo una restricción de clave externa entre las tablas Sesiones y Usuarios. Específicamente, Sessions.UID = Users.ID. A veces, quiero que Sessions.UID sea nulo. ¿Se puede permitir esto? Cada vez que trato de hacer esto, obtengo una Violación de restricción FK.SQL Server 2005: Restricción de clave externa anulable

Específicamente, estoy insertando una fila en Sesiones a través de LINQ. Configuro la Session.User = null; y me sale este error:

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.

Sin embargo, cuando se quita la línea que anula la propiedad del usuario, me sale este error en mi línea SubmitChanges:

Value cannot be null. 
Parameter name: cons

Ninguno de mis tablas tienen un campo llamado 'contras ', ni está en mi archivo DataContext.designer.cs de 5,500 líneas, ni está en el QuickWatch para ninguno de los objetos relacionados, así que no tengo idea de qué' contras 'es.

En la base de datos, Session.UID es un campo nullable int y User.ID es un int no nulo. Quiero grabar sesiones que pueden o no tener un UID, y preferiría hacerlo sin deshabilitar la restricción en esa relación FK. ¿Hay alguna forma de hacer esto?

Respuesta

27

Parecía recordar haber creado un FK anulable antes, así que realicé una prueba rápida. Como puede ver a continuación, definitivamente es factible (probado en MSSQL 2005).

Guíe las partes relevantes de sus tablas y restricciones y publíquelas para que podamos solucionar más problemas.

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

Derecha adk. +1 La definición de una clave externa es que es un valor en una tabla que debe coincidir con un valor de clave primaria en otra tabla o ser nulo. – Alan

+1

Lógicamente, tiene sentido, ¿verdad? Lo leí así: SI intento hacer referencia a un registro en otra tabla, asegúrese de que la referencia sea válida. Si no lo hago (NULO), a quién le importa. –

Cuestiones relacionadas