如何使用 EF 在外键上允许空值?

Posted

技术标签:

【中文标题】如何使用 EF 在外键上允许空值?【英文标题】:How to allow null values on Foreign keys using EF? 【发布时间】:2014-05-29 23:46:35 【问题描述】:

如何在使用 EF 的外键上允许空值?

public class User

    public User() 
     
    

    public int idUser;  get; set; 
    [Required]
    public string UserName  get; set; 
    public virtual Computer Computer get; set; 


public class Computer

    public Computer() 
    
    
    [Key, ForeignKey("User")]
    public int idUser get; set; 
    public string ComputerName get;set;
    public virtual User User  get; set; 

运行这个我在外键上得到not null

【问题讨论】:

使用 ? 关键字。喜欢:public virtual Computer? Computer get; set; 【参考方案1】:

您可以使用? 关键字。它使您的类型成为Nullable 类型。

例如int 通常不允许空值。

但是在将? 附加到int 之后,您可以为其分配空值。

int? iCanHaveNull = null;

【讨论】:

只适用于 int,但 string 或 guid 呢【参考方案2】:

如何在使用 EF 的外键上允许空值?

如果您打算采用以下方法,您的数据库表也应该允许空值:

改变

public int idUser;  get; set; 
[Required]
public string UserName  get; set; 
public virtual Computer Computer  get; set; 

public int idUser;  get; set; 
[Required]
public string UserName  get; set; 
public virtual Computer Computer get; set; 

然后改变

[Key, ForeignKey("User")] 
public int idUser  get; set; 
public string ComputerName  get; set; 
public virtual User User  get; set; 

[Key, ForeignKey("User")] 
public int? idUser  get; set; 
public string ComputerName  get; set; 
public virtual User User  get; set; 

? 字符构成一个字段nullable。确保它在您的数据库中也可以为空。

【讨论】:

字符串数据类型呢? @Luciekulza 字符串是引用类型,默认nullable 需要我同时在User?int? 上写入? 字符吗? @#!@#$ 是什么?这 ?字符是允许基本数据的可空类型(int、double、bool 等)。根据定义,Class 已经是可为空的类型。这个答案没有意义。 确实如此,但您的答案仍然不正确。你不能用?在已经可以为空的类型上。这 ?必须在 int 上? idUser 属性。如果您不相信我,请尝试您的解决方案。它不会编译。【参考方案3】:

我假设您首先使用代码。如果是这种情况,那么您在上下文类中覆盖 OnModelCreating 并添加以下行

modelBuilder.Entity<Computer>().HasOptional(c => c.User);

================ 好的,在我发布我的答案后你改变了你的帖子。

你可以使用

int?用户名

对于您的用户 ID,这将让 EF 知道您允许为空的关系。

【讨论】:

【参考方案4】:

我知道答案迟了,但这是一个重要的话题。

您正在尝试设置导航属性。如果你声明正确(如下例所示),那么:

User 类中包含的属性Computer 使用外键idComputer 引用(“指向”)计算机。 同样,Computer 类中包含的属性 User 使用外键 idUser 引用(“指向”)用户。

EF 自动引入这个外键如果

您使用[Key] 属性装饰每个实体的主键Id。每个定义的主键不得为空。 您正确声明了导航属性(例如 public virtual Computer Computer get; set; - 按照惯例,它创建了一个通过 ForeignKey 属性显式命名为 idComputer 的外键)。此外键在每个定义中都可以为空,除非您将 [Required] 属性添加到导航属性。 例如,如果您想让User 实体中引用(“指向”)Computer 的外键是强制性的,那么声明[Key, ForeignKey("idComputer"), Required] 就可以做到这一点。

EF Core 特别说明:您必须通过

在包管理器控制台中创建迁移

dotnet ef migrations add CreateMyDatabase

然后通过以下方式将其应用到数据库中:

dotnet ef database update --context myDbContext --project myProject

(将 CreateMyDatabase、myDbContext 和 myProjects 替换为您选择的名称 - 但 myDbContext 和 myProjects 必须存在于您的解决方案中)。

这是使用工具集 5.0.3,您可能需要通过 dotnet tool update --global dotnet-ef --version 5.0.3

对其进行升级

示例:

// using System.ComponentModel.DataAnnotations;
// using System.ComponentModel.DataAnnotations.Schema;

public class User


    public User() 

    [Key]
    public int Id  get; set; 
    
    [Required]
    public string UserName  get; set; 
    
    [Key, ForeignKey("idComputer")]
    public virtual Computer Computer  get; set; 


public class Computer

    public Computer() 

    [Key]
    public int Id  get; set; 

    [Required]
    public string ComputerName  get; set; 
    
    [Key, ForeignKey("idUser")]
    public virtual User User  get; set; 

public virtual User User get; set 这样的东西可能看起来很奇怪,但这是一个约定,告诉 EF 它是一个导航属性,并且在数据库表中创建的所有内容都是一个外键(这里:idUser 在表 @987654342 @)。 您可以在此处找到包含一些附加信息的良好描述:

https://www.tektutorialshub.com/entity-framework-core/ef-core-relationships-navigation-properties/

【讨论】:

以上是关于如何使用 EF 在外键上允许空值?的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 在外键上传递参数返回总是 null

Oracle SQL Developer - 在外键上添加约束

我应该在外键上使用 onDelete=cascade 吗?

同一主键上的EF多个外键关系

EF - 对于已创建的实体:无法将值 NULL 插入“Id”列、“Languages”表;列不允许空值

为什么在哈希映射中使用空值或空键是有用的?