2

I have models with datetime fields.

My code is working with models setting this reseting this fields to now. But I don't want "setting" now, but "saving" now: i.e. if I set field1 = now [0:00:00], then, 10s. later field2 = now [0:00:10] and then, 10s. later, I execute SaveChanges() I'd like to have both field set to 0:00:20 (saving time).

Edit: code example:

var context = new SomeEntities();
SomeModel model = context.GetSomeModel(...);
// SomeModel has two DateTime fields: dt1 and dt2
model.dt1 = SavingDateTimeNow(); // .... 13:42:00
// some code, i.e. Sleep(TimeSpan.FromSeconds(10));
model.dt2 = SavingDateTimeNow(); // .... 13:42:10
// again 10s. code
context.SaveChanges(); // .... 13:42:20

Edit2: More complex example:

var context = new SomeEntities();
SomeModel model = context.GetSomeModel(...);
// SomeModel has two DateTime fields: dt1 and dt2
if(someComplexCondition)model.dt1 = SavingDateTimeNow(); // .... 13:42:00
// some code from which I would know if someOtherComplexCondition is true
if(someOtherComplexCondition)model.dt2 = SavingDateTimeNow(); // .... 13:42:10
// again 10s. code
// much more code here
context.SaveChanges(); // .... 13:42:20

I want both (dt1 and dt2) to be set to ... 13:42:20, not 13:42:00 and 13:42:10

Edit3: Simplest example: I would like it to work just like django's fields with auto_now=True.

Ari
  • 3,101
  • 2
  • 27
  • 49
  • You could use the database to populate those values by using a default value of GetDate() – Tomas McGuinness Sep 28 '12 at 11:42
  • Easiest would be to set the DateTime-fields just before calling SaveChanges or see tomasmcguinness comment – Scoregraphic Sep 28 '12 at 11:45
  • @tomasmcguinness I don't know how can I do this. How can I set this fields to `GetDate()` from c# and EF? – Ari Sep 28 '12 at 11:48
  • @Scoregraphic It would be hard: there is complicated code which sometimes set some fields. I can't easily do it just before saving. – Ari Sep 28 '12 at 11:49
  • In your DB table, you would need to set the default value. This should point you in the right direction. http://msdn.microsoft.com/en-us/library/ms187872.aspx – Tomas McGuinness Sep 28 '12 at 12:05
  • @tomasmcguinness default value would be OK for new rows. I need soultion for modified rows too. – Ari Sep 28 '12 at 12:24

4 Answers4

0

Ah, so there could be multiple models which have been modified and might need the DateTime set on save.

In which case either push the boolean flags (setDt1 and SetDt2) into the model and when you make changes add those models to a list... or add a Tuple of <model,bool,bool> to a list.

Look at this question Getting all changes made to an object in the Entity Framework to see an example of then looping over those stored models to view their modified properties.

You can check an entity's EntityState to get Entities that have been added with

var addedStateEntries = Context.ObjectStateManager.GetObjectStateEntries(EntityState.Added);

and entities that have been modified with

var modifiedStateEntries = Context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified);

You can loop over them when you're ready to save and set dt1 or dt2 as appropriate


If I understand correctly then you want dt1 and dt2 to be set to DateTime.Now when you saveChanges()

In that scenario replace your call to context.SaveChanges() with a call to the below method

private void SaveModel(SomeEntities context, SomeModel model bool setDt1, bool setDt2) {
  DateTime instant = DateTime.Now;
  if (SetDt1) { model.dt1 = instant; }
  if (setDt2) { model.dt2 = instant; }
  context.SaveChanges();
}

So looking at the more complex example... I'd set a flag once I know if the date should be set on save. I've left SavingDateTimeNow() in place as I don't know if it does other tasks as well as setting dt1 to Now

var context = new SomeEntities();
SomeModel model = context.GetSomeModel(...);
var setDt1 = false;
var setDt2 = false;

// SomeModel has two DateTime fields: dt1 and dt2
if(someComplexCondition) {
 model.dt1 = SavingDateTimeNow(); // .... 13:42:00
 setDt1 = true;
}
// some code from which I would know if someOtherComplexCondition is true
if(someOtherComplexCondition) {
  model.dt2 = SavingDateTimeNow(); // .... 13:42:10
  setDt2 = true;
}
// again 10s. code
// much more code here
SaveModel(context, model, setDt1, setDt2); // .... 13:42:20
Community
  • 1
  • 1
Paul D'Ambra
  • 7,629
  • 3
  • 51
  • 96
  • @paul-dambra I added more complex example. It isn't that easy. – Ari Sep 28 '12 at 11:52
  • @Paul, I edited your answer to include what the OP wants (I think). Please feel free to rollback if I am incorrect. – Brad Rem Sep 28 '12 at 12:06
  • @BradRem I as editing at the same time sorry – Paul D'Ambra Sep 28 '12 at 12:09
  • Again, whole code is much more complex so I can't use any solution which would, at the end, check if some date need to be set to now or no. – Ari Sep 28 '12 at 12:10
  • @BradRem just looked at your edit and we wrote essentially the same code :-) – Paul D'Ambra Sep 28 '12 at 12:10
  • 1
    Then I think you need to edit your question to state more clearly the problem. You want to conditionally set fields of a model to DateTime.Now at the point you save the model? OK, so what makes it more complex than setting a boolean flag and checking it on save? – Paul D'Ambra Sep 28 '12 at 12:12
  • @Paul Because on save I could have edited many different istances of many different entity models. I want to simply save all of it (it would be one query to db). – Ari Sep 28 '12 at 12:16
0

This is not a full answer, but a number of hints to think about.

  1. You can set a StoreGeneratedPattern property for dt1 and dt2 to Computed and handle this situation on database level.
  2. You can set default value to getdate() on database level, and for new records with unspecified dt it will be set to now.
Mikhail
  • 20,685
  • 7
  • 70
  • 146
0

Why not extend your object model to include a SaveDateTime property. You then use:

dt1.SaveDateTime = true;

When you call SaveChanges() you then update all the positive flags to the current DateTime (remembering to reset after).

InContext
  • 2,461
  • 12
  • 24
  • I don't know any OnSave event. When I'm calling SaveChanges I have know idea what my logic changes. So I can't just check some more fields. It would have to be somewhere inside Entity or Models, but still I don't know how could I write it. – Ari Sep 28 '12 at 12:42
0

I found solution which isn't perfect (if you find better one, please, post it here). Here is full article: Dave Dunkin's blog: Automatic Timestamping for Entity Framework

The idea is to:

  1. Create interface for models which needs this feature
  2. Implement infreface
  3. Create methods in Entitywhich would go through all modified entities, check for entitites implementng interface and modify its datetime fields (it could be done by method in this interface)
  4. Add this methods to SavingChanges event in Entity
Ari
  • 3,101
  • 2
  • 27
  • 49