【问题标题】:How to allow null values on Foreign keys using EF?如何使用 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;}

标签: c# entity-framework entity-framework-core


【解决方案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/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多