c# - 无法定义没有 PK 的表
问题描述
我有一个名为的表AspNetUsers
,它是由创建的默认表AspNetCore.Identity
,我创建了一个名为的类User
,它继承IdentityUser
并实现了更多字段AspNetUsers
:
public class User : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
public string LockoutMessage { get; set; }
public string SessionId { get; set; }
public virtual UserDetails UserDetail { get; set; }
}
然后我创建了另一个名为 的类UserDetails
,我不需要PK
在这个表中,因为UserDetails
我需要存储可用用户的详细信息,User
其中是AspNetUsers
表:
public class UserDetails
{
//public string Id { get; set; }
public string Biography { get; set; }
public string Country { get; set; }
public string FacebookLink { get; set; }
public string TwitterLink { get; set; }
public string SkypeLink { get; set; }
public string UserId { get; set; }
public virtual User User { get; set; }
}
现在,如果我取消注释该Id
属性,则迁移效果很好,但我不需要,Id
所以我注释了该属性并执行此命令:
add-migration Initial-Migration -context DemoAppContext
update-database
在DemoAppContext
我告诉要EF
实现FK
on的类中UserDetails
:
public class DemoAppContext : IdentityDbContext<User>
{
public DemoAppContext(DbContextOptions<DemoAppContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<User>(entity =>
{
entity.HasOne(d => d.UserDetail)
.WithOne(p => p.User)
.HasForeignKey<UserDetails>(x => x.UserId);
});
}
public DbSet<UserDetails> UserDetails { get; set; }
}
命令后Add-Migration
我收到此错误:
实体类型“UserDetails”需要定义一个主键。
正如我所说,如果我注释掉Id
所有工作正常,但我不需要PK
on UserDetails
。
解决方案
正如我所说,如果我注释掉 Id 一切正常,但我不需要对 UserDetails 进行 PK
如果我理解正确,您只是不想添加额外的列(例如,Id
或UserDetailsId
)设置为 PK 。UserDetails
您要创建的表将有一个引用UserId
该表的User
表,并且UserId
将同时用作主键和外键。
事实上,没有必要拥有entity的Id
属性。UserDetails
那么为什么你的代码不起作用呢?原因是您混淆了从属实体和主体实体。
HasForeignKey<>()
方法的原型是:
public virtual ReferenceReferenceBuilder<TEntity,TRelatedEntity> HasForeignKey<TDependentEntity>
(
Expression<Func<TDependentEntity,object>> foreignKeyExpression
)
where TDependentEntity : class;
HasForeignKey<TDependentEntity>()
注意代表依赖实体的通用参数。
这是你的代码:
builder.Entity<User>(entity =>
{
entity.HasOne(d => d.UserDetail)
.WithOne(p => p.User)
.HasForeignKey<UserDetails>(x => x.UserId);
});
看到了吗?在您的代码中,entity
这里是User
Principal Entity 而不是 Dependent Entity。要修复它,请更改您的代码,如下所示:
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<User>(entity =>
{
entity.HasOne(u => u.UserDetail).WithOne(d => d.User);
});
builder.Entity<UserDetails>(entity =>
{
// set the UserId as key
entity.HasKey(d=>d.UserId);
// the relationship between `UserDetails : User` is 1-to-1
entity.HasOne(d=>d.User).WithOne(u=>u.UserDetail)
// set column `UserId` as the FK for the dependent entity , i.e. , the `UserDetails` .
.HasForeignKey<UserDetails>(u=>u.UserId);
});
}
它将同时生成一个列设置为 PrimaryKey 和 ForeignKey 的UserDetails
表:UserId
CREATE TABLE [dbo].[UserDetails] (
[Biography] NVARCHAR (MAX) NULL,
[Country] NVARCHAR (MAX) NULL,
[FacebookLink] NVARCHAR (MAX) NULL,
[TwitterLink] NVARCHAR (MAX) NULL,
[SkypeLink] NVARCHAR (MAX) NULL,
[UserId] NVARCHAR (450) NOT NULL,
CONSTRAINT [PK_UserDetails] PRIMARY KEY CLUSTERED ([UserId] ASC),
CONSTRAINT [FK_UserDetails_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [dbo].[AspNetUsers] ([Id]) ON DELETE CASCADE
);
顺便说一句,Visual Studio 的 SQL Server 对象资源管理器中似乎存在一个错误(请参阅我的问题here),导致我们无法看到已经存在的 FK 约束的错误。
但是,我们可以通过尝试使用不存在的 UserId 插入一行来证明这一点:
insert into UserDetails
(Biography,UserId)
values
('hello,wrold','here-is-a-non-existing-user-id')
它将按预期抱怨以下消息:
消息 547,第 16 级,状态 0,第 1 行
INSERT 语句与 FOREIGN KEY 约束“FK_UserDetail_AspNetUsers_UserId”冲突。冲突发生在数据库“App-EFCore-FK-Test”、表“dbo.AspNetUsers”、“Id”列中。
该语句已终止。
推荐阅读
- delphi - 如何在 Firemonkey 中创建带圆角的 ListView/Listbox?
- ios - iOS:如何清除 PDFView?
- three.js - 如何在修改后的 MeshPhysicalMaterial 着色器中更新阴影
- python - 从 csv 中删除多余的时间戳
- python - form.is_valid() 未正确验证
- pandas - 使用大量数据创建 H5 数据库错误
- android - 如何从 Kotlin 中的片段访问主机活动中的晶圆厂?
- postman - Postman 测试 - 使用变量解析 JSON 请求时出错
- python - 如何在 Windows 上激活 virtualenv?
- fonts - LaTeX 繁体中文字体,PDF中的数字不可搜索