我目前正在使用实体框架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)
在这里的用途是什么,如果我只需要使数据库列可以为空,那么我的域类中是否可以为空?
答案 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;}