实体框架7 Fluent API无法识别IsOptional()

时间:2015-12-22 05:07:30

标签: entity-framework entity-framework-core ef-fluent-api

我目前正在使用实体框架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)时,我收到以下错误:

  

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

所以,我想知道IsRequired(false)在这里的用途是什么,如果我只需要使数据库列可以为空,那么我的域类中是否可以为空?

3 个答案:

答案 0 :(得分:7)

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

  

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

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

  

也就是说,标记为可空的属性支持空值,而标记为非可空的属性必须永远不能包含空值。由此得出,将不允许将具有不可空CLR类型的属性标记为允许空值。 这与允许这样做的EF6行为不同。 [强调添加]

结果是,在EF7中,NULL列严格意味着可以为空的映射属性。如果您的媒体资源可以为空,则相关列必须为NULL,除非您使用IsRequired进行标记或配置。

对OP编辑的回应

有趣的是,我最初没有看到IsRequired(bool) API上的文档。我在6月份meeting notes找到了一个讨论点,说明等同于EF6的IsOptional()

  

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

即使这是最初的意图,取消支持的设计决定可以追溯到10月份。 (每次更新)尝试在非可空属性上设置IsRequired(false)会导致运行时错误,而不是完全删除。

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

答案 1 :(得分:3)

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

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

答案 2 :(得分:0)

在EntityFrameworkCore中没有IsOptional,但是在对面有IsRequired。如果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);
}

错误

不能将实体类型“用户”上的属性“ InterestId”标记为可为空/可选,因为该属性的类型为“字节”,而不是可为空的类型。任何属性都可以标记为不可为空/必需,但只有可为空类型且不属于主键的属性可以被标记为可为空/可选。

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

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