Entity Framework 7 流利 API 不识别 IsOptional()

Entity Framework 7 Fluent API Doesn't Recognize IsOptional()

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

modelBuilder.Entity<Article>().Property(t => t.ArticleDateModified).IsOptional();

但是 IsOptional 似乎不再是 EF7 的一部分,我想知道如何使用 EF7 实现相同的目的?

编辑: Marc 的回答确实是正确的,首先我认为它有效,因为我发现了类似 IsOptional:

的东西
builder.Entity<Article>().Property(t => t.ArticleDateModified).IsRequired(false);

但是在我 运行 没有它的情况下进行一些测试后,它将数据库列设置为可为空,因为我在我的域模型中将其标记为可为空:

public DateTime? ArticleDateModified { get; set; }

还值得注意的是,当我使 DateTime 不可为空并使用 IsRequired(false) 时,出现以下错误:

The property 'ArticleDateModified' on entity type 'Article' cannot be marked as nullable/optional because the type of the property is 'DateTime' which is not a nullable type. Any property can be marked as non-nullable/required, but only properties of nullable types and which are not part of primary key can be marked as nullable/optional.

所以,我想知道 IsRequired(false) 在这里有什么用,如果我要做的就是使数据库列可以为空,就是让它在我的域中可以为空 class?

Em...声明 属性 为可空?

class Article
{
    public DateTime? ArticleDateModified {get;set;}
}

根据此 documentation page 中的说明,似乎已取消对以声明方式执行此操作的支持。即:

A property whose CLR type cannot contain null cannot be configured as optional. The property will always be considered required by Entity Framework.

在 GitHub、specifically:

上托管的项目的设计讨论中可以看出这是有意的

That is, a property marked as nullable supports null values, while a property marked as non-nullable must never contain null values. It follows from this that marking a property which is of a non-nullable CLR type as allowing nulls will not be allowed. This is different from the EF6 behavior where this is allowed. [emphasis added]


结果是,在 EF7 中,NULL 列严格表示可以为 null 的映射 属性。如果您的 属性 可以为空,则关联的列必须是 NULL 除非您使用 IsRequired.

标记或配置它

对 OP 编辑​​的响应

这很有趣,我最初没有看到 IsRequired(bool) API 上的文档。我在某个 6 月 meeting notes 找到了一个讨论点,指出这个 相当于 EF6 的 IsOptional():

.IsOptional() - We'll provide this functionality via calling Required(false)
.IsRequired() - Provide Required() with the same functionality

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

虽然现在是多余的,但 API 不能在不破坏有效代码的情况下删除:它不是用单独的 IsRequired(bool)IsRequired() 定义实现的,而是用单个 IsRequired(bool required = true).如果它被删除并替换为无参数版本,那将是一个重大变化。

EntityFrameworkCore 中没有 IsOptional,但有 IsRequired 来做相反的事情。默认情况下,如果 C# 类型可为空,则字段可为空。

此外,您不能使用 IsRequire(false) 方法设置作为另一个 table 主键的外键。如果你这样做,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);
}

Error

实体类型 'User' 上的 属性 'InterestId' 不能标记为 nullable/optional 因为 属性 的类型是 'byte'不是可为空的类型。任何 属性 都可以标记为 non-nullable/required,但只有可空类型且不属于主键的属性才能标记为 nullable/optional.

所以最好的方法是像这样使 属性 可以为空。

public byte? InterestId {get; set;} 
public Interest Interest {get; set;}