必需的属性,但可以为空,通过代码优先的实体框架

Posted

技术标签:

【中文标题】必需的属性,但可以为空,通过代码优先的实体框架【英文标题】:Required property but Nullable, Entity Framework through Code First 【发布时间】:2016-12-12 11:58:33 【问题描述】:

如何使数据库代码迁移需要的属性(用于字段验证)但可为空?

我确实有一个包含一千个条目的数据库表。最近需要添加所需的 DateTime 属性。

    [Required]
    [Display(Name = "Birth", Order = 10)]
    public DateTime? Birth  get; set;  

如果我设置[Required] 注释,代码优先迁移将在列声明中添加NOT NULL。但是,所有当前条目都没有“出生”数据。它将为 NULL。

Birth 属性应该是视图字段验证所必需的,但它可以在数据库中为空。这有可能吗?

我已经尝试添加“?” (可为空)到属性和“虚拟”没有成功。

【问题讨论】:

如果你编辑数据,你不应该在视图中使用数据模型 - 你应该使用视图模型,DateTime 可以用[Required] 装饰,但从数据模型中省略. 【参考方案1】:

使用您的模型进行数据库/实体通信。

为您的 UI 层使用视图模型。在 ViewModel 中的属性上标记为必需,在模型上标记为 Nullable。根据需要在您的代码中执行强制转换。将所有与 UI 相关的属性装饰(如 Display、validation/etc)也移动到 ViewModel。

可以通过 NuGet 包管理器使用 AutoMapper 插件 available 自动执行转换。

【讨论】:

【参考方案2】:

一种快速的方法是覆盖数据库上下文的 OnModelCreating() 方法。

这样:

public class AppContext : DbContext

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   
      // ...
      modelBuilder.Entity<YourModelEntity>.Property(p => p.Birth).IsOptional();
   


或者另一种正确的方法是您可以为您的模型创建一个通用 EntityTypeConfiguration 类型的扩展类,然后以这种方式将此特定配置添加到 OnModelCreating() 方法中的 DBModelBuilder:

public class YourModelTypeConfiguration : EntityTypeConfiguration<YourModelType>

    public YourModelTypeConfiguration()
    
        // ... some other configurations ;

        Property(p => p.Birth).IsOptional();
    

请注意,您需要

using System.Data.Entity.ModelConfiguration; 

在你的类文件的顶部。

然后在 OnModelCreating() 方法中添加:

    public class AppContext : DbContext

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   
      // quick and dirty solution
      // modelBuilder.Entity<YourModelEntity>.Property(p => p.Birth).IsOptional()

      // cleaner solution
      modelBuilder.Configurations.Add(new YourModelTypeConfiguration());
   


这样您就可以将您的特定配置分开,而不是将所有内容混合在一起。

在应用代码首次迁移时,“出生”数据库字段应该可以为空。

我希望这会有所帮助。

【讨论】:

以上是关于必需的属性,但可以为空,通过代码优先的实体框架的主要内容,如果未能解决你的问题,请参考以下文章

实体框架 CTP4 代码优先:映射受保护的属性

实体框架代码优先 - 通过主键将子实体添加到父实体

实体框架代码优先 - 不可为空类型的默认值

带有外键的实体框架选择为空?

设置可选:必需的关系实体框架 - 流式 API

实体框架代码优先与 Guid