Creating a Base Class for all entities in Entity Framework 5 in DB first approach

c#, entity-framework

Solution

If you are doing database first you can always edit the T4 template to do what you want. In your Solution Explorer, expand the MyEntities.edmx file and find the MyEntities.tt file and open that up.

On line 307 you should have the following method:

public string EntityClassOpening(EntityType entity)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        _code.Escape(entity),
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)));
}

You will want to change this to:

public string EntityClassOpening(EntityType entity)
{
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        _code.Escape(entity),
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType) ?? "MyBaseClass"));
}

You can see that if there is no BaseType provided (which you can do in the GUI, but that is for having a single Entity inherit from another entity) then we want the entity to inherit from MyBaseClass.

Now when you save this it will regenerate all your entities and they will inherit from MyBaseClass now. Simple as that.

Problem

I have few properties like CreatedDate, ModifiedDate, VersionNo on every table. I need to change/ add values for these properties every time I modify the entity. I thought I could create a Base class with these Properties and let the Entities derive from this Base class and during SavingChanges based on ObjectState I could change the Values and Save, that way my audit entries will be isolated from the entity and the thing will be abstracted. But since I am new to Entity Framework , I am finding it difficult to understand how will I handle the mappings, etc.. If anyone can suggest ideas for implementing this, that would be really helpful. Repository code is like below: ``` public class GeneralRepository<T> : IRepository<T> where T : class { private ObjectSet<T> _set; private ObjectContext _context; public GeneralRepository(ObjectContext context) { if (context == null) throw new ArgumentNullException("context"); _context = context; // sets the context _set = context.CreateObjectSet<T>(); // returns the Object Set } #region Methods to override to work with ObjectGraphs . /// <summary> /// To insert data from entity into a table. /// </summary> /// <param name="entity"></param> public virtual void Insert(T entity) { if (entity == null) throw new ArgumentNullException("entity"); _set.AddObject(entity); } /// <summary> /// To delete entity from a table. /// </summary> /// <param name="entity"></param> public virtual void Delete(T entity) { if (entity == null) throw new ArgumentNullException("entity"); _set.Attach(entity); _set.DeleteObject(entity); } /// <summary> /// To update Entity into the table /// </summary> /// <param name="entity"></param> public virtual void Update(T entity) { if (entity == null) throw new ArgumentNullException("entity"); _set.Attach(entity); _context.ObjectStateManager.ChangeObjectState(entity, EntityState.Modified); } /// <summary> /// To get th entire table contents /// </summary> /// <returns></returns> public IQueryable<T> GetAll() { return _set; } ``` }

Original source