EF Code First Readonly专栏

dae*_*aai 22 entity-framework code-first entity-framework-4.1

我首先使用EF Code和数据库第一种方法."使用Database.SetInitializer(null);"

我的表有两列createddate和amendddate.它们由SQL Server使用触发器管理.我们的想法是,当数据输入发生时,这些列通过触发器获取数据.

现在我想做的是从EF Code的第一个角度来看这个只读.即我希望能够从我的应用程序中看到创建日期和已记录的日期,但我不想修改这些数据.

我尝试在setter上使用私有修饰符,但没有运气.当我尝试向表中添加新数据时,它试图将DateTime.Max日期输入到数据库,该数据库从SQL服务器抛出错误.

任何的想法?

Lad*_*nka 36

您不能使用私有修饰符,因为EF本身需要在加载实体时设置属性,而Code First只能在属性具有公共setter时执行此操作(与EDMX相反,其中私有setter是可能的(1),(2)) .

你需要做的是标记您CreatedDateDatabaseGeneratedOption.Identity和你AmendDateDatabaseGeneratedOption.Computed.这将允许EF正确加载数据库中的数据,在插入或更新后重新加载数据,以便该实体在您的应用程序中是最新的,同时它不允许您更改应用程序中的值,因为设置的值应用程序永远不会传递给数据库.从面向对象的角度来看,它不是一个非常好的解决方案,但从功能的角度来看,它正是您想要的.

您可以使用数据注释来执行此操作:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public DateTime CreatedDate { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
public DateTime AmendDate { get; set; }
Run Code Online (Sandbox Code Playgroud)

或者OnModelCreating在派生上下文中使用简洁的覆盖API :

modelBuilder.Entity<YourEntity>() 
            .Property(e => e.CreatedDate)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<YourEntity>()
            .Property(e => e.AmendDate)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed);
Run Code Online (Sandbox Code Playgroud)

  • @koraytaylan - 不要对日期字段使用`DatabaseGeneratedOption.Identity`。相反,使用`DatabaseGeneratedOption.Computed`,这是Ladislav 在他的回答中建议的。 (2认同)