I used the technique shows in this answer ( https://stackoverflow.com/a/6282472/2045385 ) to create a TrackingDbContext from which I inherit many of my contexts now, and any entity which needs CreateDate/LastModified properties inherits from the TrackingBase entity. It has worked very well so far.
Until today.
Ultimately I fixed my problem already by changing the way I add this new entity into a collection, but I don't really understand why the original isn't working... and I'd like to understand that as I figure its going to come back to bite me again and again until I do understand it.
Originally I was adding a new status record to an orderItem by creating a new status object and adding it to the collection of statusItems of the order object, like so.
var newlyPaidOrders = shopDB.shopOrders
.Where(o => o.status == "NEW" &&
o.payment >= o.cost)
.ToList();
for (int i = 0; i< newlyPaidOrders.Count; i++)
{
var paidOrder = newlyPaidOrders.ElementAt(i);
foreach ( var paidItem in paidOrder.orderItems )
{
shopOrderItemStatus sois = new shopOrderItemStatus
{
status = "PAID",
agent = "cronjob",
shopOrderItem = paidItem,
comment = ""
};
paidItem.shopItemOrderStatus.Add(sois);
}
paidOrder.status = "PAID";
}
if (newlyPaidOrders.Count > 0)
shopDB.SaveChanges();
After SaveChanges() I can see that the new status object is created in the database, but.... hey! the CreateDate/LastModified were not updated, they are both null. I put in breakpoints into the TrackingDbContext.SaveChanges() and sure enough, the filter searching for entities which are Modified or Added is coming up empty. Whoah.. how can that be?
IEnumerable<ObjectStateEntry> objectStateEntries =
from e in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)
where
e.IsRelationship == false &&
e.Entity != null &&
typeof(TimestampTrackingBase).IsAssignableFrom(e.Entity.GetType())
select e;
This morning I got up and, as is often the case, sleep gives a new perspective. I decided to add the item to the context.dbset directly rather than simply modifying the object I already had in my hands, to see if there was a difference, like so.
for (int i = 0; i< newlyPaidOrders.Count; i++)
{
var paidOrder = newlyPaidOrders.ElementAt(i);
foreach ( var paidItem in paidOrder.orderItems )
{
shopOrderItemStatus sois = new shopOrderItemStatus
{
status = "PAID",
agent = "cronjob",
shopOrderItem = paidItem,
comment = ""
};
shopDB.shopOrderItemStatus.Add(sois);
}
paidOrder.status = "PAID";
}
And there is.. it now works as intended, the CreateDate/ModifiedDates are not null. But why does the original not work? What I can't get my head around is the concept that (a) the new entity is added to the database.. the automatic DetectChanges() system must be working... and surely it had the "Added()" state... (b) somehow that state was not sufficient to be found in the filter for newly added items and thus the Created/ModifiedDate fields weren't updated.