[英]Is it possible to set a non primary key as foreign key in another table?
More specifically, I would like to set the Email
column from AspNetUsers
table as foreign key in another table.更具体地说,我想将
AspNetUsers
表中的Email
列设置为另一个表中的外键。
I hope to have explained my problem well.我希望能很好地解释我的问题。
If you're just asking about SQL Server (and not Entity Framework), then I quoteth Microsoft's documentation :如果您只是询问 SQL Server(而不是实体框架),那么我引用Microsoft 的文档:
A foreign key constraint doesn't have to be linked only to a primary key constraint in another table.
外键约束不必只链接到另一个表中的主键约束。 Foreign keys can also be defined to reference the columns of a UNIQUE constraint in another table.
也可以定义外键以引用另一个表中的 UNIQUE 约束的列。
Therefore to answer your stated question directly:因此,直接回答您提出的问题:
UNIQUE CONSTRAINT
or have a non-filtered UNIQUE INDEX
applied to them, then yes , you can.UNIQUE CONSTRAINT
或应用了未过滤的UNIQUE INDEX
,则是的,您可以。FOREIGN KEY
constraint columns referencing UNIQUE CONSTRAINT
columns. UNIQUE CONSTRAINT
列的FOREIGN KEY
约束列。 There are subtle differences between UNIQUE CONSTRAINT
and UNIQUE INDEX
, though the main difference is indicating intent - so you should prefer UNIQUE CONSTRAINT
over UNIQUE INDEX
when you're using a column - or columns - as a secondary key . UNIQUE CONSTRAINT
和UNIQUE INDEX
之间存在细微差别,但主要区别在于表明意图- 因此当您使用一列或多列作为辅助键时,您应该更喜欢UNIQUE CONSTRAINT
不是UNIQUE INDEX
。
Entity Framework 6 :实体框架 6 :
VIEW
s to make EF6 play-nice with FK references to UNIQUE KEY
constraints, but some reports suggest that modern versions of EF6 do support this natively.VIEW
变通办法使 EF6 在 FK 引用UNIQUE KEY
约束时更好玩,但一些报告表明现代版本的 EF6确实支持这一点。 Entity Framework Core :实体框架核心:
HasPrincipal()
with HasForeignKey()
to define both a secondary-key on TPrincipal
and the foreign-key on TDependant
that points to that secondary-key.HasPrincipal()
与HasForeignKey()
来定义两个辅助键TPrincipal
和外键TDependant
指向该次级键。 As for your scenario, specifically: dbo.AspNetUsers
:至于你的场景,特别是:
dbo.AspNetUsers
:
Assuming that you want to use the Email
column to uniquely identify users, then I recommend that you don't do that : Generally speaking, it's a bad idea to use mutable data (ie data that can change) as a key.假设您想使用
Email
列来唯一标识用户,那么我建议您不要这样做:一般来说,使用可变数据(即可以更改的数据)作为键是一个坏主意。 Keys must be unique and ideally should be immutable - and while an e-mail address can be unique in some contexts (eg your system won't allow multiple users to share the same e-mail address) they aren't immutable (users can and do change e-mail addressees).键必须是唯一的,理想情况下应该是不可变的 - 虽然电子邮件地址在某些情况下可以是唯一的(例如,您的系统不允许多个用户共享同一个电子邮件地址),但它们不是一成不变的(用户可以并更改电子邮件地址)。
Another caveat: in order to use a UNIQUE CONSTRAINT
and UNIQUE INDEX
as a foreign-key target then those column(s) cannot be filtered or have NULL
s - but dbo.AspNetUser.Email
is nvarchar(256) NULL
, so you'll need to ensure all users have distinct email addresses set first .另一个警告:为了使用
UNIQUE CONSTRAINT
和UNIQUE INDEX
作为外键目标,那么这些列不能被过滤或有NULL
s - 但dbo.AspNetUser.Email
是nvarchar(256) NULL
,所以你会需要确保所有的用户都有不同的电子邮件地址,首先设置。
Having said that, this will work:话虽如此,这将起作用:
-- 1. Change `Email` from `NULL` to a `NOT NULL` column, as `UNIQUE CONSTRAINT` columns cannot contain duplicates or nulls:
ALTER TABLE dbo.AspNetUsers
ALTER COLUMN [Email] nvarchar(256) NOT NULL;
-- 2. Create a UNIQUE CONSTRAINT over the `Email` column, so SQL Server knows every row has a distinct value in that column:
ALTER TABLE dbo.AspNetUsers
ADD CONSTRAINT UQ_Email UNIQUE ( Email );
-- 3. Create a new table with a FOREIGN KEY in the other table:
CREATE TABLE dbo.OtherTable (
Etc nvarchar(50) NOT NULL,
UserEmail nvarchar(256) NULL,
CONSTRAINT FK_Users_by_email FOREIGN KEY ( UserEmail ) REFERENCES dbo.AspNetUsers ( [Email] )
);
i was able to create a foreign key to a non-pk column.我能够为非 pk 列创建外键。 no issues.
没有问题。
CREATE TABLE [dbo].[t1](
[id] [int] NOT NULL,
[fldKey] [int] NULL,
CONSTRAINT [PK_t1] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
CREATE TABLE [dbo].[t2](
[id] [int] NOT NULL,
[t1] [int] NULL,
CONSTRAINT [PK_t2] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
ALTER TABLE [dbo].[t2] WITH CHECK ADD CONSTRAINT [FK_t2_t1] FOREIGN
KEY([t1])
REFERENCES [dbo].[t1] ([fldKey])
GO
ALTER TABLE [dbo].[t2] CHECK CONSTRAINT [FK_t2_t1]
GO
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.