开发者

How can I add default values to a property when saving using Code First EF4.1?

I started by creating some models like this:

public abstract class EditableBase
{
    public DateTime CreatedOn { get; set; }
    public DateTime ModifiedOn { get; set; }

    public int CreatedBy { get; set; }
    public int ModifiedBy { get; set; }
}

public class Project : EditableBase
{
    public int ProjectId { get; set; }
    public string ProjectName { get; set; }
}

And I use this line when the app starts:

Database.SetInitializer<ModelContext>(
            new DropCreateDatabaseIfModelChanges<ModelContext>());

A table called Projects is created with all the properties mentioned above as columns... this is exactly what I wanted.

However, now I need populate some default values when I issue a SaveChanges() on DbContext. When I save I need to update the ModifiedOn and ModifiedBy properties with the appropriate values.

Normally I would at least do the DateTime values on the database side (either a trigger or a stored procedure) however this is obviously no开发者_如何学编程t an option here since the database will be dropped anytime a class changes. And since I did code first I do not have a model designer that I can tweak the properties on.

What I would like to do is add a method in the EditableBase class that gets called when the SaveChanges() is executed, thus keeping all the logic involved in one place. Is it possible to do this? What is the best way to achieve my goal?


Override SaveChanges in your derived DbContext:

public override int SaveChanges()
{
    foreach(var entry in ChangeTracker.Entries<EditableBase>())
    {
        var entity = entry.Entity;
        if (entry.State == EntityState.Added)
        {
            entity.CreatedOn = ...;
            entity.CreatedBy = ...;
        }
        else if (entry.State == EntityState.Modified)
        {
            entity.ModifiedOn = ...;
            entity.ModifiedBy = ...;
        }
    }

    return base.SaveChanges();
}

I'm only not sure if generic Entries will work directly with your base type becasue it is not actually mapped as base entity. There is also non generic version so you can rewrite it to more complex linq query or test each entry's entity type in loop.


Well, you have complete control over the code for your entities. I'd imagine you would probably want to implement an IPropertyChanged like pattern to update your properties.


Did consider the two options in this post where you do something on the setter (or constructor)?

The default attribute solution seems a good one.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜