简体   繁体   English

是否可以将非主键设置为另一个表中的外键?

[英]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.我希望能很好地解释我的问题。

Yes and No是和否

SQL Server, specifically: SQL Server,特别是:

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:因此,直接回答您提出的问题:

  • Is it possible to set a non primary key as foreign key in another table?是否可以将非主键设置为另一个表中的外键?
    • If they're "normal" columns, then no, because otherwise SQL Server has no way of knowing that those values will uniquely identify each row.如果它们是“普通”列,则否,否则 SQL Server 无法知道这些值将唯一标识每一行。
    • But if the columns are in either in a UNIQUE CONSTRAINT or have a non-filtered UNIQUE INDEX applied to them, then yes , you can.但是,如果列位于UNIQUE CONSTRAINT或应用了未过滤的UNIQUE INDEX ,则是的,您可以。
    • This requires SQL Server 2005 or later.这需要 SQL Server 2005 或更高版本。 (I might be wrong, but I don't believe SQL Server 2000 supported FOREIGN KEY constraint columns referencing UNIQUE CONSTRAINT columns. (我可能错了,但我不相信 SQL Server 2000 支持引用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 CONSTRAINTUNIQUE INDEX之间存在细微差别,但主要区别在于表明意图- 因此当您使用一列或多列作为辅助键时,您应该更喜欢UNIQUE CONSTRAINT不是UNIQUE INDEX

Entity Framework实体框架

  • Entity Framework 6 :实体框架 6

    • I'll admit I'm unsure.我承认我不确定。 I remember having to really fight EF6 and use workarounds like 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.我记得必须真正与 EF6 抗争,并使用VIEW变通办法使 EF6 在 FK 引用UNIQUE KEY约束时更好玩,但一些报告表明现代版本的 EF6确实支持这一点。
  • Entity Framework Core :实体框架核心

    • Yes.是的。 Use 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 CONSTRAINTUNIQUE INDEX作为外键目标,那么这些列不能被过滤或有NULL s - 但dbo.AspNetUser.Emailnvarchar(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] )
);

Yes you can make foreign key by principal key in asp.net core, by using fluent api.是的,您可以使用 fluent api 通过 asp.net core 中的主键创建外键。 You can see an example from microsoft doc from here您可以从此处查看来自 microsoft doc 的示例

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.

相关问题 Entity Framework 5.0非主键的复合外键-可能吗? - Entity Framework 5.0 composite foreign key to non primary key - is it possible? AspNetUsers的主键作为另一个表的外来 - Primary key of AspNetUsers as foreign of another table 实体框架代码优先使用具有另一个表的非主键的外键 - Entity Framework Code First approach foreign key with non primary key of another table 如何用petapoco更新另一个表中的外键主键? - how to update a primary key that is also a foreign key in another table with petapoco? 使用ASPNETUSER表电子邮件字段作为另一个表中的主键,即主外键 - Use ASPNETUSER Table Email Field as a primary key in another table, primary foreign key nhibernate通过外键而不是主键连接到表 - nhibernate join to table by foreign key not primary key 如何将非主键派生到另一个表 - How to derive a non-primary key to another table 如何将一个表中的主(代理)键添加到另一个表的外键中? - How to add a primary (Surrogate) key from one table into a foreign key of another table? 如何更新在另一个表中作为外键引用的表的主键? - How to Update the primary key of table which is referenced as foreign key in another table? 从链接到许多表的另一个表的主键中获取外键字段 - Get foreign key field from primary key in another table that linked to many table
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM