实体框架代码优先空外键
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
【讨论】:
以上是关于实体框架代码优先空外键的主要内容,如果未能解决你的问题,请参考以下文章