0

I'm trying to initialze the CreatedAt and Guid value the first time a record is created via Entity Framework. But when performing an update using the same model, I don't want to overwrite that value. (As it is a timestamp for creation)

This is what I have currently:

 public EntityBase()
    {
        if(this.CreatedAt == null)
            this.CreatedAt = DateTimeOffset.Now;

        this.UUId = new Guid();
        this.UpdatedAt = DateTimeOffset.Now;         
    }

Whenever I create an instance of this model the constructor will be invoked and a new DateCreated value. Would this be a valid way?

Dninja
  • 99
  • 1
  • 7
  • 1
    The best approach is to use a database default constraint for `CreatedAt` and mark the property as database-generated. – Gert Arnold Jan 16 '18 at 14:45
  • If you are looking to handle create and update dates automatically in entity framework, we use [this technique](https://stackoverflow.com/questions/26355486/entity-framework-6-audit-track-changes) of overriding savechanges() and marking those classes with an interface. – Steve Greene Jan 16 '18 at 15:27

3 Answers3

2

You can simply remove the "if" from your constructor and leave it as is - assigning default values to the fields. For a newly created entity, those will be used as default. When your application will set some values and store it to some storage and at a later time try to retrieve it, the persisted values will be restored, because the data layer will try to set those properties to their persisted values, and will call the property setters, no matter what the value is.

public EntityBase()
{
    this.CreatedAt = DateTimeOffset.Now;
    this.UUId = new Guid();
    this.UpdatedAt = this.CreatedAt;
}

When updating a record, that record would be already retrieved, hence have non-default values for the creation date.

Also note, how I've set the "UpdatedAt" to the same "CreatedAt" - to not get a different time value (there can be minor difference in your example) - a bit unrelated tip.

Artak
  • 2,819
  • 20
  • 31
  • Hmm I kind of get what you're saying thanks. Why won't the data be overwritten? If I bind the model to an entity, won't it overwrite the date and UUId? – Dninja Jan 17 '18 at 09:37
  • The class constructor will be called as the first thing. Then only any overwrites will happen. So any assignments happen after the constructor execution hence overwrite the default values. – Artak Jan 17 '18 at 16:09
  • Exactly! That's why im confused. So If I had to assign or update CreatedAt or UUID it would indeed overwrite the entities property. So how does this solve it? I guess, I must just only explicitly assign the UpdatedAt and Not the UUId and CreatedAt, and they will never be overriden? – Dninja Jan 20 '18 at 16:12
  • I will be able to assist you better if you could also share some code where you access the data store. Are you using EF? – Artak Jan 20 '18 at 16:18
  • I dont get why this was -1'd :/ I went through all my questions and edited them (took a good while) and still I cannot post anything. This really sucks. – Dninja Sep 01 '18 at 07:22
0

Edit:

Or in constructor:

if (this.CreatedAt == default(DateTimeOffset))
{
     this.CreatedAt = DateTimeOffset.Now;
}
garret
  • 1,134
  • 8
  • 16
  • Many thanks man, but I don't really understand that. If CreatedAt is the default value for DateTimeOffset, then set it to now? How is that achieving what I need? – Dninja Jan 16 '18 at 14:56
  • Normaly, if CreatedAt is set to any value, it will ignore any attempt to overright it. If it's in default value, then save current date. – garret Jan 16 '18 at 14:59
  • I see. So if the date is 1900-01-1 (or whatever it is), it means it has not been explicitly set, so set it. If it has been explicitly set, ignore it ? – Dninja Jan 17 '18 at 09:40
  • I dont get why this was -1'd :/ I went through all my questions and edited them (took a good while) and still I cannot post anything. This really sucks. – Dninja Sep 01 '18 at 07:22
0

With C# 7, just use an auto prop with a default:

public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;

That will set it to DateTimeOffset.UtcNow only if it's null.

Chris Pratt
  • 232,153
  • 36
  • 385
  • 444
  • I dont get why this was -1'd :/ I went through all my questions and edited them (took a good while) and still I cannot post anything. This really sucks. – Dninja Sep 01 '18 at 07:22