DbContext Entity framework Datetime.Now fields

梦想的初衷 提交于 2019-12-11 19:13:46

问题


Have two fields with data type datetime.

  • Added
  • Modified

When inserting new record values for both fields must be System.DateTime.Now; but when updating only Modified needs to be changed.

I can set StoreGeneratedPattern to Computed and handle Modified field with GETDATE() in database but problem is field Added.

My guess is that I have to override SavingChanges() or something similar but don't know how.

EDIT : What I have try so far

  • Added another class in my project with fallowing code

    namespace Winpro
    {
        public partial class Customer
        {
            public Customer()
            {
                this.Added = DateTime.UtcNow;
            }
        }
    }
    

    but then cannot build solution

    Type 'Winpro.Customer' already defines a member called 'Customer' with the same parameter types


回答1:


One option is to define a constructor for the type that sets the field.

Big important note: unless you know exactly what you're doing, always store dates and times in a database in UTC. DateTime.Now is the computer's local time which can vary according to daylight savings, timezone changes (brought about by political/legislative reasons), and can end up rendering date information useless. Use DateTime.UtcNow.

public partial class MyEntity {
    public MyEntity() {
        this.Added = DateTime.UtcNow;
    }
}



回答2:


We did something quite similar in the past.

There was the need to store both Date and Time and the responsible for creating the record. Also, on every change, dispite if there's an audit record or not, the base record should also get a Date and Time and the user responsible for the changes.

Here's what we have done:

Interfaces

To add some standard behavior and make things more extensible, we've created two interfaces, as follows:

public interface IAuditCreated
{
   DateTime CreatedDateTime { get; set; }
   string CreationUser { get; set; }
}

public interface IAuditChanged
{
   DateTime LastChangeDateTime { get; set; }
   string LastChangeUser { get; set; }
}

Override SaveChanges() to add some automatic control

public class WhateverContext : DbContext
{
   // Some behavior and all...

   public override int SaveChanges()
   {
      // Added ones...
      var _entitiesAdded = ChangeTracker.Entries()
         .Where(_e => _e.State == EntityState.Added)
         .Where(_e => _e.Entity.GetType().GetInterfaces().Any(_i => _i == typeof(IAuditCreated)))
         .Select(_e => _e.Entity);
      foreach(var _entity in _entitiesAdded) { /* Set date and user */ }

      // Changed ones...
      var _entitiesChanged = ChangeTracker.Entries()
         .Where(_e => _e.State == EntityState.Modified)
         .Where(_e => _e.Entity.GetType().GetInterfaces().Any(_i => _i == typeof(IAuditChanged)))
         .Select(_e => _e.Entity);
      foreach(var _entity in _entitiesChanged) { /* Set date and user */ }

      // Save...
      return base.SaveChanges();
   }
}

Do not simply copy and paste!

This code was written a few years ago, on the age of EntityFramework v4. It assumes that you have already detected changes (ChangeTracker available) and some other.

Also, we have absolutely no idea of how this code impacts performance on any way. That's because the usage of this system is much or related to viewing than updating and also because it's a desktop application, so we have plenty available memory and processing time to waste.

You should take that into account and you might find a better way to implement this. But the whole idea is the same: filter which entities are being updated and which are being added to properly handle that.

Another approach

There are many approaches to this. One other that might be better for performance on some cases (but also more complex) is to have some sort of proxy, similar to an EF proxy, handling that.

Again, even with an empty interface, it's good to have one to clearly distinguish between auditable records and regular ones.

If possible to force all of them having the same property name and type, do it.



来源:https://stackoverflow.com/questions/21295123/dbcontext-entity-framework-datetime-now-fields

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!