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;}
我目前正在使用 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;}