为啥Required IdentityUser 属性会导致可以为空的数据库字段?
Posted
技术标签:
【中文标题】为啥Required IdentityUser 属性会导致可以为空的数据库字段?【英文标题】:Why does a Required IdentityUser property result in a nullable database field?为什么Required IdentityUser 属性会导致可以为空的数据库字段? 【发布时间】:2021-09-03 20:11:20 【问题描述】:我想要求特定类型的所有实体在我的 ASP.NET MVC 应用程序中都有相应的用户,并且这是在数据库级别强制执行的,即作为不可为空的字段。但是,当我在模型类的 IdentityUser
属性上设置 Required
属性时,如下所示:
using Microsoft.AspNetCore.Identity;
using System.ComponentModel.DataAnnotations;
namespace Test.Models
public class Foo
public int Id get; set;
[Required]
public IdentityUser User get; set;
生成的相应迁移将UserId
表字段设置为可为空:
UserId = table.Column<string>(type: "TEXT", nullable: true)
我已经读过 Table Per Hierarchy 会导致这种情况,但我没有使用任何继承。
我错过了什么?有没有办法实现我想要的?
【问题讨论】:
在DbContext.OnModelConfiguring
中明确设置属性是否有效?
请给全班看好吗?
@abdusco 我在 API 文档中找不到对 OnModelConfiguring
的任何引用。
@Serge 我已经添加了整个类代码。
【参考方案1】:
您还可以使用Fluent API 来配置您的约束。
public class Foo
public int Id get; set;
public string UserId get; set;
public IdentityUser User get; set;
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
public DbSet<Foo> Foos get; set;
protected override void OnModelCreating(DbModelBuilder modelBuilder)
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Foo>()
.HasRequired(c => c.User)
.WithMany(d => d.Foos)
.HasForeignKey(c => c.UserId);
【讨论】:
【参考方案2】:尝试修复你的课程
public class Foo
[Key]
public int Id get; set;
[Required]
public string UserId get; set;
[ForeignKey(nameof(UserId))]
public IdentityUser User get; set;
Net 5 自动创建一个影子属性 UserId 以便您可以保存您的 Foo 类。由于您使用了 [Required],EF 自动添加它可以为空。如果此属性不能为 null(例如,如果它是 int 类型(不是 int?!)),则不需要 [Required] 属性。
【讨论】:
IdentityUser 主键是一个字符串,而不是一个 int。 感谢您的回答。你知道为什么需要额外的财产吗?为什么我不能将Required
属性放在User
上并且它可以工作?
@SimonMorgan 因为您无法将整个用户记录保存在 Foo 数据库表中。您只能保存一列值。保存主键是在需要加入时查找用户的最佳方式。 Net 5 可以创建影子属性 UserId,但最好控制它。
但即使没有 UserId
属性,EF 也发现它是 AspNetUsers 表的外键并在 Foo 表上创建了一个 UserId
字段,但它设置为可为空,即使User
属性为 [Required]
。那么为什么你必须显式地向模型添加一个UserId
属性并将that 设置为[Required]
以将数据库UserId
字段设置为不可为空?
是的,正如我已经说过的,它被称为影子属性,它仅用于保存。但是最好明确地添加它,以便您可以在代码中使用它。例如,如果您只需要一个 userId,则不需要包含整个用户记录。以上是关于为啥Required IdentityUser 属性会导致可以为空的数据库字段?的主要内容,如果未能解决你的问题,请参考以下文章
为啥调用vector.reserve(required + 1) 比vector.reserve(required) 快?
为啥在 Protocol Buffers 3 中删除了 required 和 optional
required_once() 中的变量未定义但可与 require() 一起使用,为啥?
linux rsync 同步过来的目录为啥属主属组是mysql