Entity framework 实体框架7 Fluent API不';t识别等位基因()

Entity framework 实体框架7 Fluent API不';t识别等位基因(),entity-framework,entity-framework-core,ef-fluent-api,Entity Framework,Entity Framework Core,Ef Fluent Api,我目前正在使用entity framework 7(以前使用EF 6)在Asp.Net 5项目中设置数据库,当我想使某些列为空时,我会使用: modelBuilder.Entity<Article>().Property(t => t.ArticleDateModified).IsOptional(); 但是在我运行了一些没有它的测试之后,它将数据库列设置为null,因为我在域模型中将它标记为null: public DateTime? ArticleDateModified

我目前正在使用entity framework 7(以前使用EF 6)在Asp.Net 5项目中设置数据库,当我想使某些列为空时,我会使用:

modelBuilder.Entity<Article>().Property(t => t.ArticleDateModified).IsOptional();
但是在我运行了一些没有它的测试之后,它将数据库列设置为null,因为我在域模型中将它标记为null:

public DateTime? ArticleDateModified { get; set; }
还值得注意的是,当我将
DateTime
设置为不可空并使用
IsRequired(false)
时,我得到了以下错误:

实体类型“Article”上的属性“ArticleDateModified”不能标记为可空/可选,因为该属性的类型为“DateTime”,而不是可空类型。任何属性都可以标记为不可空/必需,但只有可空类型且不属于主键的属性才能标记为可空/可选


因此,我想知道如果要使数据库列可为null,我所要做的就是使它在我的域类中可为null,那么这里的IsRequired(false)有什么用呢。。。是否将属性声明为可空

class Article
{
    public DateTime? ArticleDateModified {get;set;}
}
根据本文中的注释,似乎取消了对以声明方式这样做的支持。也就是说:

CLR类型不能包含null的属性不能配置为可选属性。实体框架始终认为该属性是必需的

在GitHub上托管的项目的设计讨论中可以看出这是故意的:

也就是说,标记为可空的属性支持空值,而标记为不可空的属性决不能包含空值。因此,不允许将不可为null的CLR类型的属性标记为允许为null。这与允许的EF6行为不同。[重点补充]


结果是,在EF7中,
NULL
列严格地表示一个可为NULL的映射属性。如果属性可为空,则相关列必须为
NULL
,除非您使用
IsRequired
标记或配置它


对OP编辑的响应

这很有趣,我最初没有看到
IsRequired(bool)
API上的文档。我在六月份的某个时候发现了一个关于它的讨论点,指出这将相当于EF6的
isonational()

.IsOptional()-我们将通过调用Required(false)来提供此功能
.IsRequired()-提供具有相同功能的Required()

尽管这是最初的意图,但取消支持的设计决定从10月份开始生效。(每次更新)尝试在不可为空的属性上设置
IsRequired(false)
会导致运行时错误,而不是完全删除


虽然现在是多余的,但如果不破坏有效代码,就无法删除API:它不是使用单独的
IsRequired(bool)
IsRequired()
定义实现的,而是使用单个
IsRequired(bool required=true)
。如果将其删除并替换为无参数版本,这将是一个突破性的更改。

EntityFrameworkCore中没有ISO选项,但需要执行oposite。默认情况下,如果C#类型可为空,则字段可为空

此外,您不能使用IsRequire(false)方法设置外键,它是另一个表的主键。如果执行此操作,EntityframeworkCore将抛出错误

public class User
{
  public int Id {get; set;}
  public string Username {get;set}
  public byte Interest {get;set;}
  public Interest Interest {get;set;}
}

public class Interest
{
  public byte Id {get;set;}
  public string Name {get;set;}
}
ApplicationDbContext

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   base.OnModelCreating(modelBuilder);

   modelBuilder.Entity<User>()
     .property(u => u.InterestId)
     .isRequired(false);
}

我在下面做了一些研究,但首先我应该问:你能通过从
ArticleDateModified
中删除空值并查看当你使用
IsRequired(false)
映射时在数据库中生成什么来检验这个假设吗?如果该列为空,不管他们在10月份做出了什么决定,他们基于6月份的设计决定构建它的事实将压倒10月份的决定,至少在下一个主要版本发布之前,因为(技术上)RTM API不会从RC1更改,删除或禁用API将是一个突破性的更改。如果该列不为空,则表示该列已被禁用。@MarcL。我用答案编辑了这个问题。
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   base.OnModelCreating(modelBuilder);

   modelBuilder.Entity<User>()
     .property(u => u.InterestId)
     .isRequired(false);
}
public byte? InterestId {get; set;} 
public Interest Interest {get; set;}