I am currently creating a proof-of-concept application that implements the repository pattern. I decided to use the classic ADO.NET and Entity Framework as my sample ORMs. This is currently how my IRepository and IUnitOfWork interfaces are implemented.
public interface IUnitOfWork : IDisposable
{
IEmployeeRepository Employees { get; }
int Complete();
}
public interface IRepository<TEntity> where TEntity : class
{
TEntity Get(int id);
IEnumerable<TEntity> GetAll();
IEnumerable<TEntity> Find(Expression<Func<TEntity, bool>> predicate);
TEntity SingleOrDefault(Expression<Func<TEntity, bool>> predicate);
void Add(TEntity entity);
void AddRange(IEnumerable<TEntity> entities);
void Remove(TEntity entity);
void RemoveRange(IEnumerable<TEntity> entities);
}
All is well on my Entity Framework implementation for updating objects because it has a built-in ChangeTracker class that checks the states of the objects.
static void Main(string[] args)
{
var context = new RPContextDbFactory().CreateDbContext(null);
using (var unitOfWork = new Data.EF.UnitOfWork(context))
{
//using Entity Framework
var employee = unitOfWork.Employees
.Get(1);
employee.FirstName = "Foo";
unitOfWork.Complete(); // <-- Calls DbContext.SaveChanges()
}
}
My problem is how I can implement the same concept on a classic ADO.NET implementation since it does not have a ChangeTracker class like EF.
static void Main(string[] args)
{
var builder = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
IConfigurationRoot configuration = builder.Build();
var connectionString = configuration.GetConnectionString("RPContext");
using (var unitOfWork = new Data.StoredProcedures.UnitOfWork(connectionString))
{
//using classic ADO.NET
var employee = unitOfWork.Employees
.Get(1);
employee.FirstName = "Foo";
unitOfWork.Complete(); //<-- Nothing will happen.
}
}
//UnitOfWork implementation for my classic ADO.NET
public class UnitOfWork : IUnitOfWork
{
public UnitOfWork(string connectionString)
{
Employees = new EmployeeRepository(connectionString);
}
public IEmployeeRepository Employees { get; private set; }
public int Complete()
{
throw new NotImplementedException();
}
public void Dispose()
{
throw new NotImplementedException();
}
}
One of the advice I saw in other sites was to implement a ChangeTracker sort of logic inside the UnitOfWork class of my ADO.NET namespace but I am not really sure how to implement it. How will my UoW know which objects was changed?