Я вызвал у меня некоторую проблему с моим уровнем доступа к данным. В этом конкретном случае у меня есть таблица, которая содержит потенциально 5 типов «сущности». Это, в основном, компания, клиент, сайт и т. Д. Тип продиктован PositionTypeId в таблице. Все они находятся в одной таблице, так как все они имеют одну и ту же структуру данных; PositionId, описание и код.Нужна помощь в сортировке основной абстрактной головной боли в моем DAL
У меня есть основной абстрактный класс следующим образом:
public abstract class PositionProvider<T> : DalProvider<T>, IDalProvider where T : IPositionEntity
{
public static PositionProvider<T> Instance
{
get
{
if (_instance == null)
{
// Create an instance based on the current database type
}
return _instance;
}
}
private static PositionProvider<T> _instance;
public PositionType PositionType
{
get
{
return _positionType;
}
}
private PositionType _positionType;
// Gets a list of entities based on the PositionType enum's value.
public abstract List<T> GetList();
internal void SetPositionType(RP_PositionType positionType)
{
_positionType = positionType;
}
}
Я хочу, чтобы затем иметь возможность поставить все общий код в пределах класса inherting, который либо SQL или Oracle на основе. Это моя реализация SQL:
public class SqlPositionProvider<T> : PositionProvider<T> where T : IPositionEntity
{
public override List<T> GetList()
{
int positionTypeId = (int)this.PositionType;
using (SqlConnection cn = new SqlConnection(Globals.Instance.ConnectionString))
{
SqlCommand cmd = new SqlCommand("Get_PositionListByPositionTypeId", cn);
cmd.Parameters.Add("@PositionTypeId", SqlDbType.Int).Value = positionTypeId;
cmd.CommandType = CommandType.StoredProcedure;
cn.Open();
return this.GetCollectionFromReader(this.ExecuteReader(cmd));
}
}
}
Я затем создать класс для каждого типа следующим образом (это не является CustomerProvider в качестве примера):
public class CustomerProvider
{
public static PositionProvider<CustomerEntity> Instance
{
get
{
if ((int)PositionProvider<CustomerEntity>.Instance.PositionType == 0)
{
PositionProvider<CustomerEntity>.Instance.SetPositionType(PositionType.Customer);
}
return PositionProvider<CustomerEntity>.Instance;
}
}
}
Это все работает сказочно ... до тех пор, Я понял, что у меня есть определенные функции, которые связаны конкретно с определенными типами позиций. То есть Мне нужно, чтобы все клиенты (который является IPositionType) на основе прав пользователя.
Так что мне нужно добавить еще один абстрактный метод:
public abstract List<CustomerEntity> GetCustomersByUserPermission(Guid userId);
Теперь, очевидно, я не хочу, чтобы это в моем PositionProvider абстрактного класса, как это будет означать, что метод будет появляться при работе с сайтом/поставщика компании ,
Как добавить этот и другие дополнительные методы без дублирования кода в SqlPositionProvider?
Edit:
Единственная идея, которую я придумал, чтобы отделить PositionProvider из в общей собственности CustomerProvider, SiteProvider, etcProvider:
public abstract class CustomerProvider
{
public CustomerProvider()
{
this.Common.SetPositionType(PositionType.Customer);
}
public PositionProvider<CustomerEntity> Common
{
get
{
if (_common == null)
{
DalHelper.CreateInstance<PositionProvider<CustomerEntity>>(out _common);
}
return _common;
}
}
private PositionProvider<CustomerEntity> _common;
public static CustomerProvider Instance
{
get
{
if (_instance == null)
{
DalHelper.CreateInstance<CustomerProvider>(out _instance);
}
return _instance;
}
}
private static CustomerProvider _instance;
public abstract List<CustomerEntity> GetCustomersByUserPermission(Guid userId);
}
Это позволило бы мне чтобы поместить конкретный код в пределах CustomerProvider.Instance.MyNonGenericMethod()
, а затем получить доступ к PositionProvider
, я мог бы сделать CustomerProvider.Instance.Common.GetList()
... Это действительно похоже на хак.
Я просто могу сказать вам: используйте NHibernate, и он сделает все для вас. –
Я бы предпочел использовать EntitySpaces на самом деле - это лучше и быстрее - но я не могу использовать его в этом проекте. – GenericTypeTea
Я думаю, что лучше отделить «специальные» методы, а не общие (они должны быть меньше), и не выставлять их как одно свойство, а переопределять методы (делегировать на композит), это позволит вам иметь более чистый API –