I'm very new to the Entity Framework and trying to understand how to best architect my data layer in way that makes the most sense from the prospective of a developer. I'm working on a proof of concept using the AventureWorks database. I built a generic repository that I use to query any table in the database. Following is a short, but compilable (I hope), snippet (the actual code has methods to update, delete, etc.):
/// <summary>
/// A generic repository for working with data in the database
/// </summary>
/// <typeparam name="T">A POCO that represents an Entity Framework entity</typeparam>
public class DataRepository<T> : IDisposable, IRepository<T> where T : class
{
/// <summary>
/// The context object for the database
/// </summary>
private ObjectContext _context;
/// <summary>
/// The IObjectSet that represents the current entity. Used to query, add, modify and delete objects of the specified entity.
/// </summary>
private IObjectSet<T> _objectSet;
/// <summary>
/// Initializes a new instance of the DataRepository class
/// </summary>
public DataRepository()
: this(new AdventureWorksEntities())
{
}
/// <summary>
/// Initializes a new instance of the DataRepository class
/// </summary>
/// <param name="context">The Entity Framework ObjectContext</param>
public DataRepository(ObjectContext context)
{
_context = context;
_objectSet = _context.CreateObjectSet<T>();
}
/// <summary>
/// Gets all records as an IQueryable
/// </summary>
/// <returns>An IQueryable object, containing the results of the query</returns>
public IQueryable<T> GetQuery()
{
return from x in _objectSet select x;
}
/// <summary>
/// Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Releases all resources used by the WarrantManagement.DataExtract.Dal.ReportDataBase
/// </summary>
/// <param name="disposing">A boolean value indicating whether or not to dispose managed resources</param>
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
if (_context != null)
{
_context.Dispose();
_context = null;
}
}
}
}
In my ASP.NET demo app, I can use the repository, as follows, to get an Employee record (notice the reference to Contact):
using (DataRepository repository = new DataRepository())
{
this.GridView1.DataSource = from x in repository.GetQuery()
select new
{
x.MaritalStatus,
x.Contact.FirstName,
x.Contact.LastName,
x.BirthDate
};
this.GridView1.DataBind();
}
This could work out well, but my concern is that the View now has knowledge of the database schema, which I don't like. For example, if I were to decide to move the FirstName and LastName columns into the Employee table, I would have to rewrite all lines of code where I referenced the columns as I did in the snippet above. My preference is to change the conceptual model by creating properties off of the Employee class and have Entity Framework automatically perform the JOIN, as necessary.
Firstly, are there any "lessons learned" from anybody that has designed a model like I have proposed? Anything negative that I should look out for? Secondly, are there any alternatives that I should be aware of?