Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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;
    }

}

like image 863
Nisha_Roy Avatar asked Jan 15 '23 01:01

Nisha_Roy


2 Answers

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.

like image 89
Jeff Treuting Avatar answered Jan 30 '23 23:01

Jeff Treuting


I think you are on the right lines, create a base class called "EntityBase" or whatever name suits your preference and add those properties.

I would then change the repository class declaration code above to be:

public class GeneralRepository<T> : IRepository<T> where T : EntityBase

You will then be able to set the common properties within the repository where required.

As far as mapping goes, I would definately look at the Entity Framework 5 Power Tools as you have mentioned you are database first, my experience however has always been mapping using the fluent API.

Also... definately look at some of the benefits that DBContext would provide you with as opposed to ObjectContext which you are currently using within your repository.

Thanks

like image 31
BenjaminPaul Avatar answered Jan 30 '23 21:01

BenjaminPaul