using System;
using System.Data;
using System.Data.Objects;
using System.Linq;
namespace Metavision.Infra.Data
{
/// <summary>
/// Implementação de UnitOfWork para EntityFramework (ObjectContext)
/// Basicamente funciona abstraindo as operações do ObjectContext
/// Permitindo trabalhar com injeção de dependência
/// </summary>
public class ObjContextUnitOfWork : UnitOfWorkBase, IUnitOfWork
{
#region Members
private readonly ObjectContext _objContext;
#endregion
#region Ctor
public ObjContextUnitOfWork(ObjectContext objectContext = null)
{
_objContext = objectContext ?? Container.GetService<ObjectContext>(false);
}
#endregion
#region Implementation of IUnitOfWork
public T Find<T>(params object[] keyValues) where T : class, new()
{
var setName = GetObjectSet<T>().EntitySet.Name;
var entityKey = new EntityKey(setName, "Id", keyValues);
return (T)_objContext.GetObjectByKey(entityKey);
}
public void Add<T>(T entity) where T : class
{
GetObjectSet<T>().AddObject(entity);
}
public void Remove<T>(T entity) where T : class
{
GetObjectSet<T>().DeleteObject(entity);
}
public IQueryable<T> Get<T>() where T : class
{
return GetObjectSet<T>();
}
private ObjectSet<T> GetObjectSet<T>() where T : class
{
ObjectSet<T> set;
if (Sets.ContainsKey(typeof(T)))
set = (ObjectSet<T>)Sets[typeof(T)];
else
{
set = _objContext.CreateObjectSet<T>();
Sets[typeof(T)] = set;
}
return set;
}
internal override void StartTransaction()
{
if (!InTransaction)
{
_objContext.Connection.Close();
if (_objContext.Connection.State != ConnectionState.Open)
{
_objContext.Connection.Open();
CurrentTransaction = _objContext.Connection.BeginTransaction();
}
}
}
public int Commit()
{
var hasChanges = StackRepositories.Any(w => w.HasChanges);
if (!hasChanges) return 0;
try
{
StartTransaction();
var count = _objContext.SaveChanges();
CurrentTransaction.Commit();
SetHasChangesToFalse();
return count;
}
catch (Exception)
{
RollBack();
return -1;
}
}
public void RollBack()
{
SetHasChangesToFalse();
if (!InTransaction) return;
CurrentTransaction.Rollback();
}
#endregion
#region Implementation of IDisposable
public override void Dispose()
{
base.Dispose();
_objContext.Dispose();
}
#endregion
}
}