Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
226 views
in Technique[技术] by (71.8m points)

c# - Entity Framework/SQL2008 - How to Automatically Update LastModified fields for Entities?

If i have the following entity:

public class PocoWithDates
{
   public string PocoName { get; set; }
   public DateTime CreatedOn { get; set; }
   public DateTime LastModified { get; set; }
}

Which corresponds to a SQL Server 2008 table with the same name/attributes...

How can i automatically:

  1. Set the CreatedOn/LastModified field for the record to now (when doing INSERT)
  2. Set the LastModified field for the record to now (when doing UPDATE)

When i say automatically, i mean i want to be able to do this:

poco.Name = "Changing the name";
repository.Save(); 

Not this:

poco.Name = "Changing the name";
poco.LastModified = DateTime.Now;
repository.Save();

Behind the scenes, "something" should automatically update the datetime fields. What is that "something"?

I'm using Entity Framework 4.0 - is there a way that EF can do that automatically for me? (a special setting in the EDMX maybe?)

From the SQL Server side, i can use DefaultValue, but that will only work for INSERT's (not UPDATE's).

Similarly, i can set a default value using a constructor on the POCO's, but again this will only work when instantiating the object.

And of course i could use Triggers, but it's not ideal.

Because i'm using Entity Framework, i can hook into the SavingChanges event and update the date fields here, but the problem is i need to become "aware" of the POCO's (at the moment, my repository is implemented with generics). I would need to do some sort of OO trickery (like make my POCO's implement an interface, and call a method on that). I'm not adversed to that, but if i have to do that, i would rather manually set the fields.

I'm basically looking for a SQL Server 2008 or Entity Framework 4.0 solution. (or a smart .NET way)

Any ideas?

EDIT

Thanks to @marc_s for his answer, but i went with a solution which is better for my scenario.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I know I'm a little late to the party, but I just solved this for a project I'm working on and thought I'd share my solution.

First, to make the solution more re-usable, I created a base class with the timestamp properties:

public class EntityBase
{
    public DateTime? CreatedDate { get; set; }
    public DateTime? LastModifiedDate { get; set; }
}

Then I overrode the SaveChanges method on my DbContext:

public class MyContext : DbContext
{
    public override int SaveChanges()
    {
        ObjectContext context = ((IObjectContextAdapter)this).ObjectContext;

        //Find all Entities that are Added/Modified that inherit from my EntityBase
        IEnumerable<ObjectStateEntry> objectStateEntries =
            from e in context.ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified)
            where
                e.IsRelationship == false &&
                e.Entity != null &&
                typeof(EntityBase).IsAssignableFrom(e.Entity.GetType())
            select e;

        var currentTime = DateTime.Now;

        foreach (var entry in objectStateEntries)
        {
            var entityBase = entry.Entity as EntityBase;

            if (entry.State == EntityState.Added)
            {
                entityBase.CreatedDate = currentTime;
            }

            entityBase.LastModifiedDate = currentTime;
        }

        return base.SaveChanges();
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...