Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Code First Readonly column

I am using EF Code first with database first approach. "with Database.SetInitializer(null);"

My table has two columns createddate and amendddate. They are managed by SQL Server using triggers. The idea is that when data entry happens then these columns gets data via triggers.

Now What I want to do is to make this read only from EF Code first point of view. I.e. I want to be able to see the createddate and ameneded dates from my app but I dont want to amend these data.

I have tried using private modifiers on setter but no luck.When I try to add new data to the table it tried to enter DateTime.Max date to the database which throws error from SQL server.

Any idea?

like image 418
daehaai Avatar asked Jul 03 '11 18:07

daehaai


People also ask

How can we specify computed generated column in Entity Framework?

The Entity Framework Core Fluent API HasComputedColumnSql method is used to specify that the property should map to a computed column. The method takes a string indicating the expression used to generate the default value for a database column.

Which of the following are inheritance strategies can be used with EF Code First?

Inheritance with EF Code First: Table per Hierarchy (TPH)


1 Answers

You cannot use private modifiers because EF itself needs to set your properties when it is loading your entity and Code First can only do this when a property has public setter (in contrast to EDMX where private setters are possible (1), (2)).

What you need to do is mark your for CreatedDate with DatabaseGeneratedOption.Identity and your AmendDate with DatabaseGeneratedOption.Computed. That will allow EF to correctly load data from the database, reload data after insert or update so that entity is up to date in your application and at the same time it will not allow you to change the value in the application because the value set in the application will never be passed to the database. From an object oriented perspective it is not a very nice solution but from the functionality perspective it is exactly what you want.

You can do it either with data annotations:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTime CreatedDate { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public DateTime AmendDate { get; set; } 

Or with fluent API in OnModelCreating override in your derived context:

modelBuilder.Entity<YourEntity>()              .Property(e => e.CreatedDate)             .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); modelBuilder.Entity<YourEntity>()             .Property(e => e.AmendDate)             .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed); 
like image 57
Ladislav Mrnka Avatar answered Sep 20 '22 20:09

Ladislav Mrnka