Entity Framework Code-First 空外键

141

我有一个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;}
}

错误: 因为相应的主键值不存在,无法插入外键值。[外键约束名称=Country_Users]


如果我错了,请您指出来。在Code First ASP.NET MVC-5 Entity Framework中,默认情况下外键是可为空的。 - Unbreakable
1
如果我们想使它非空,我们需要使用流畅的API,如果不是,则用“Required”属性进行装饰。我说得对吗? - Unbreakable
2
如果我们两者都不做,那么外键将默认为可空。 - Unbreakable
5个回答

215

你必须使外键可为空:

public class User
{
    public int Id { get; set; }
    public int? CountryId { get; set; }
    public virtual Country Country { get; set; }
}

47
虚拟化技术对于懒加载是必要的。 - Ladislav Mrnka
6
Virtual 还增加了变更跟踪功能,但并非总是需要的。关于我们唯一需要虚拟化的时候通常是在集合上,但具体情况可能因人而异(YMMV)。 - Dan VanWinkle
1
@TravisJ 如果 user.Country 返回 null,那么最好捕获异常,或者使用 if(不太优雅)。 - SparK
@Jay 在 vb.net 中使用 Nullable(Of Integer)Integer? - BrainSlugs83
14
此外 -- 这似乎不适用于基于Guid的键。(它会使它们可为空,但是当保存将外键设置为null的记录到数据库时,由于自动生成的外键约束而失败) :-( - BrainSlugs83
显示剩余6条评论

14

我更喜欢这个(以下):

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,但以上代码已经修复了这个问题。


这正是我遇到的问题。我的实体中甚至没有导航属性,所以发生这种情况有点奇怪。 - perustaja

10

我现在有同样的问题,我有一个外键,我需要将其设置为空,要解决这个问题,您应该放置

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

在DBContext类中,很抱歉回复你晚了:)


6
"WithOptional"不再适用于EFCore...现在只有"WithOne"。 - user1034912

1

1
在 EF 7 中:
entity.Property(e => e.propertyName).IsRequired(false);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接