实体框架代码优先空外键

Posted

技术标签:

【中文标题】实体框架代码优先空外键【英文标题】:Entity framework code-first null foreign key 【发布时间】:2011-08-05 20:14:53 【问题描述】:

我有一个 User Country 模型。一个用户属于一个国家,但可能不属于任何一个(空外键)。

如何设置?当我尝试插入一个国家为空的用户时,它告诉我它不能为空。

型号如下:

 public class User
    public int CountryId  get; set; 
    public Country Country  get; set; 


public class Country
    public List<User> Users get; set;
    public int CountryId get; set;

错误:A foreign key value cannot be inserted because a corresponding primary key value does not exist. [ Foreign key constraint name = Country_Users ]"

【问题讨论】:

如果我错了,请您纠正我。在 code first asp.net mvc - 5 entity framework 中,外键默认为 NULLABLE。 如果我们想让它不可为空。如果没有,我们需要使用流利的 api,然后使用“必需”属性进行装饰。我说的对吗? 如果我们都不这样做,那么外键将默认为 Nullable 【参考方案1】:

你必须让你的外键可以为空:

public class User

    public int Id  get; set; 
    public int? CountryId  get; set; 
    public virtual Country Country  get; set; 

【讨论】:

延迟加载需要虚拟。 Virtual 还添加了更改跟踪,这并不总是需要的。关于我们唯一想要虚拟的时间是在集合上,但 YMMV。 @LadislavMrnka - 当 id 为空(引发异常)时尝试获取导航属性时,延迟加载将如何工作? @TravisJ user.Country 返回 null 然后...要么捕获异常(最佳),要么使用 if (eww) 另外——这似乎不适用于基于 Guid 的键。 (当然,这使它们可以为空,但是由于自动生成的外键约束,将外键设置为空的记录保存到数据库失败。):-(【参考方案2】:

我更喜欢这个(下):

public class User

    public int Id  get; set; 
    public int? CountryId  get; set; 
    [ForeignKey("CountryId")]
    public virtual Country Country  get; set; 

因为 EF 在数据库表中创建了 2 个外键:CountryId 和 CountryId1,但上面的代码修复了该问题。

【讨论】:

这正是我遇到的问题。我的实体中什至没有导航属性,所以无论如何都会发生这种情况有点奇怪。【参考方案3】:

我现在也有同样的问题, 我有外键,我需要把它设为可空, 要解决这个问题,你应该把

    modelBuilder.Entity<Country>()
        .HasMany(c => c.Users)
        .WithOptional(c => c.Country)
        .HasForeignKey(c => c.CountryId)
        .WillCascadeOnDelete(false);

在 DBContext 类中 很抱歉这么晚才回复你:)

【讨论】:

'WithOptional' 对 EFCore 无效...只有 'WithOne'【参考方案4】:

我建议阅读 Microsoft 指南以使用 EF Code First 中的Relationships, Navigation Properties and Foreign Keys,就像这张图片。

指南链接如下:

https://docs.microsoft.com/en-gb/ef/ef6/fundamentals/relationships?redirectedfrom=MSDN

【讨论】:

以上是关于实体框架代码优先空外键的主要内容,如果未能解决你的问题,请参考以下文章

主键外键和索引的区别?

主键外键和索引的区别?

无法插入具有空外键的实体

Mysql主键外键和索引的区别

主键外键和索引的区别?

数据库建模:按实体类型的空外键