I am trying to create a one-to-one relationship that is optional on one side between a User table and a UserInfo table. The specifications are that a UserInfo must have exactly one User, while a User can have one or zero UserInfos. Also we require that the foreign key exist in the UserInfo table so that the columns of the User table are not modified. We would like to use the relationship in C# LINQ-to-SQL, e.g., user.UserInfo.Email = "test@test.com",userInfo.User`, etc.
The T-SQL for the tables and the foreign key from UserInfos to Users is (roughly):
CREATE TABLE [dbo].[Users](
[UserId] [int] IDENTITY(1,1) NOT NULL,
[Username] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_dbo.Users] PRIMARY KEY CLUSTERED ( [UserId] ASC ),
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[UserInfos](
[UserInfoId] [int] IDENTITY(1,1) NOT NULL,
[UserId] [int] NOT NULL,
[Email] [varchar](250) NOT NULL,
CONSTRAINT [PK_UserInfo] PRIMARY KEY CLUSTERED ( [UserInfoId] ASC ),
CONSTRAINT [UQ_UserId] UNIQUE NONCLUSTERED ( [UserId] ASC )
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[UserInfos] WITH CHECK
ADD CONSTRAINT [FK_UserInfos.UserID_Users.UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[Users] ([UserId])
GO
ALTER TABLE [dbo].[UserInfos] CHECK CONSTRAINT [FK_UserInfos.UserID_Users.UserId]
GO
The problem is that if I define a foreign key from Users.UserId (the primary key) to UserInfos.UserId (which is, I understand, the correct way to define a non-optional one-to-one relationship) then performing the LINQ-to-SQL code user.UserInfo = null also sets the user.UserId to default(int).
Here is the T-SQL I use to define the foreign key between Users and UserInfos:
ALTER TABLE [dbo].[Users] WITH CHECK
ADD CONSTRAINT [FK_Users.UserId_UserInfos.UserId] FOREIGN KEY([UserId])
REFERENCES [dbo].[UserInfos] ([UserId])
GO
ALTER TABLE [dbo].[Users] CHECK CONSTRAINT [FK_Users.UserId_UserInfos.UserId]
GO
If I do not define this foreign key, then I get no LINQ-to-SQL property on a User allowing me to access the UserInfo. How can I have a relationship between the table Users and UserInfos that is traversable with LINQ-to-SQL, while at the same time allowing this relationship to be null from the User side? Thank you.
You can do this but you’re approaching it from the wrong side.
When you call
the exception states that
LINQ-to-SQL thinks you are trying to remove the relationship between the two items; and in an indirect way you are. But the exception is just a reiteration of what you’ve stated yourself – a
UserInfomust have aUser. You’re unlinking the two objects but you aren’t removing theUserInfo– you’re leaving an orphanedUserInfoin your context which cannot be persisted to the database (due to the foreign key constraint).The answer? Delete the
UserInfo.