potential rewrite of DAM to be single non-generic instance

This commit is contained in:
Ryan Peters 2020-10-15 23:05:21 -04:00
parent 82245a693f
commit 7ad01a2586
5 changed files with 181 additions and 5 deletions

View File

@ -44,5 +44,15 @@ namespace COA.EnterpriseServices.DataAccess.EntityFramework
.ToList();
}
}
public ICollection<T> Raw(string command, params object[] parameters)
{
using (var context = new QuickBaseContext())
{
return context.Set<T>()
.FromSqlRaw(command, parameters)
.ToList();
}
}
}
}

View File

@ -37,5 +37,11 @@ namespace COA.EnterpriseServices.DataAccess.QuickBase
// we'll never get data from QB
return null;
}
public ICollection<T> Raw(string command, params object[] parameters)
{
// not supported
return null;
}
}
}

View File

@ -5,6 +5,102 @@ using System.Linq.Expressions;
namespace COA.EnterpriseServices.DataAccess
{
public class DataAccessManager2
{
private static readonly IDictionary<string, string[]> enabledDataAccess = new Dictionary<string, string[]>
{
#region Creditor
["COA.EnterpriseServices.DataAccess.Entities.Creditor"] = new[]
{
"COA.EnterpriseServices.DataAccess.QuickBase.QuickBaseDataAccess",
"COA.EnterpriseServices.DataAccess.EntityFramework.EntityDataAccess"
},
#endregion
#region Client
["COA.EnterpriseServices.DataAccess.Entities.Client"] = new[]
{
"COA.EnterpriseServices.DataAccess.QuickBase.QuickBaseDataAccess",
"COA.EnterpriseServices.DataAccess.EntityFramework.EntityDataAccess"
}
#endregion
};
public ICollection<T> Get<T>(Expression<Func<T, bool>> query) where T : class, IRecord
{
return Invoke<T, ICollection<T>>(d => d.Get(query));
}
public bool Add<T>(T item) where T : class, IRecord
{
return Invoke<T, bool>(d => d.Add(item));
}
public bool Update<T>(T item) where T : class, IRecord
{
item.Modified = DateTime.Now;
return Invoke<T, bool>(d => d.Update(item));
}
public bool Update<T>(int id, Action<T> update) where T : class, IRecord
{
var item = Get<T>(id);
update(item);
return Update(item);
}
public T Get<T>(int id) where T : class, IRecord
{
var item = Get<T>(i => i.Id == id);
if (item != null && item.Any())
{
return item.FirstOrDefault();
}
return default;
}
private TResult Invoke<T, TResult>(Func<IDataAccess<T>, TResult> func) where T : class, IRecord
{
var results = new List<TResult>();
var dataAccessInstances = GetEnabledDataAccess<T>();
foreach (var dataAccessInstance in dataAccessInstances)
{
results.Add(func(dataAccessInstance));
}
// if the "EF" version invokes first, return that value
return results.FirstOrDefault(r => r != null && !r.Equals(default(TResult)));
}
private ICollection<IDataAccess<T>> GetEnabledDataAccess<T>() where T : class, IRecord
{
var type = typeof(T);
// load data access based on active configuration
return Dependencies.Container
.GetAllInstances<IDataAccess<T>>()
.Select(i => new
{
Instance = i,
Type = i.GetType()
})
.Where(i => enabledDataAccess.ContainsKey(type.FullName) && enabledDataAccess[type.FullName].Any(a => i.Type.FullName.StartsWith(a)))
.OrderBy(i => i.Type.Name.StartsWith("QuickBase", StringComparison.OrdinalIgnoreCase))
.Select(i => i.Instance)
.ToList();
}
}
/// <summary>
/// Provides a wrapper around <see cref="IDataAccess{T}"/> as well as additional convenience CRUD methods
/// </summary>

View File

@ -1,15 +1,17 @@
using AutoMapper;
using COA.EnterpriseServices.Creditors;
using COA.EnterpriseServices.DataAccess.Entities;
using System.Collections.Generic;
namespace COA.EnterpriseServices.DataAccess.Helpers
{
public class CreditorHelper
{
private readonly DataAccessManager<Creditor> creditorDataAccess;
private readonly DataAccessManager<SettlementAttempt> settlementAttemptDataAccess;
private readonly DataAccessManager<Entities.Creditor> creditorDataAccess;
private readonly DataAccessManager<Entities.SettlementAttempt> settlementAttemptDataAccess;
private readonly IMapper mapper;
public CreditorHelper(DataAccessManager<Creditor> creditorDataAccess, DataAccessManager<SettlementAttempt> settlementAttemptDataAccess, IMapper mapper)
public CreditorHelper(DataAccessManager<Entities.Creditor> creditorDataAccess, DataAccessManager<Entities.SettlementAttempt> settlementAttemptDataAccess, IMapper mapper)
{
this.creditorDataAccess = creditorDataAccess;
this.settlementAttemptDataAccess = settlementAttemptDataAccess;
@ -24,9 +26,48 @@ namespace COA.EnterpriseServices.DataAccess.Helpers
return mapper.Map<Creditors.Creditor>(creditor);
}
public SettlementAttempt GetSettlementAttempt(int id)
public Creditors.SettlementAttempt GetSettlementAttempt(int id)
{
return settlementAttemptDataAccess.Get(id);
var attempt = settlementAttemptDataAccess.Get(id);
return mapper.Map<Creditors.SettlementAttempt>(attempt);
}
public ICollection<Creditors.SettlementAttempt> GetSettlements(SettlementAttemptFilter filter)
{
var dal2 = new DataAccessManager2();
dal2.Get<Entities.Creditor>(c => c.ClientLastName == "Peters");
return DBWrapper.ExecuteProcedure(QuickbaseConnectionString, "uspCreditorPortal_SettlementAttemptGet", cmd =>
{
if (filter != null)
{
cmd.CommandTimeout = 0;
cmd.Parameters.AddWithValue("@SettlementAttemptID", filter.SettlementAttemptId);
cmd.Parameters.AddWithValue("@CreditorProfileID", filter.CreditorProfileId);
cmd.Parameters.AddWithValue("@CreditorID", filter.CreditorId);
cmd.Parameters.AddWithValue("@CreditorContactID", filter.CreditorContactId);
cmd.Parameters.AddWithValue("@FirstPaymentDateStart", filter.FirstPaymentDateStart);
cmd.Parameters.AddWithValue("@FirstPaymentDateEnd", filter.FirstPaymentDateEnd);
cmd.Parameters.AddWithValue("@ResponseDateStart", filter.ResponseDateStart);
cmd.Parameters.AddWithValue("@ResponseDateEnd", filter.ResponseDateEnd);
cmd.Parameters.AddWithValue("@PortalSubmissionDateStart", filter.PortalSubmissionDateStart);
cmd.Parameters.AddWithValue("@PortalSubmissionDateEnd", filter.PortalSubmissionDateEnd);
if (filter.SettlementAttemptIds.AnyAndNotNull())
{
cmd.Parameters.Add("@SettlementAttemptIDs", SqlDbType.Structured).Value = CreateIdsTable(filter.SettlementAttemptIds);
}
else if (filter.CreditorIds.AnyAndNotNull())
{
cmd.Parameters.Add("@CreditorIDs", SqlDbType.Structured).Value = CreateIdsTable(filter.CreditorIds);
}
}
return cmd.ToList<SettlementAttempt>();
});
}
public bool AddCreditor(Creditors.Creditor creditor)

View File

@ -6,10 +6,33 @@ namespace COA.EnterpriseServices.DataAccess
{
public interface IDataAccess<T> where T : class, IRecord
{
/// <summary>
/// Adds an item of type <typeparamref name="T"/> to the context
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
bool Add(T item);
/// <summary>
/// Updates an item of type <typeparamref name="T"/> in the context
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
bool Update(T item);
/// <summary>
/// Gets an item collection of type <typeparamref name="T"/> from the context
/// </summary>
/// <param name="query"></param>
/// <returns></returns>
ICollection<T> Get(Expression<Func<T, bool>> query);
/// <summary>
/// Allows support for invoking a raw command if supported by the instance
/// </summary>
/// <param name="command"></param>
/// <param name="parameters"></param>
/// <returns></returns>
ICollection<T> Raw(string command, params object[] parameters);
}
}