我使自己的数据访问层出现了问题。在此特定实例中,我有一个表,其中可能包含5种类型的“实体”。这些基本上是公司,客户,站点等。类型由表中的PositionTypeId决定。它们都在同一个表中,因为它们都具有相同的数据结构。 PositionId,说明和代码。
我有一个主要的抽象类,如下所示:
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;
}
}
然后,我希望能够将所有常规代码放入基于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中重复代码?
编辑:
我想出的唯一想法是将PositionProvider分为CustomerProvider,SiteProvider等提供者的公共属性:
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
。 最佳答案
如果我理解正确,则需要一种在子类上包括某种方法的方法,但不是全部。
如果可以对所需的其他方法进行分组,则可以使用接口,实现该接口并在子级(组合)中使用此新类的实例。
对此的简化是所有子类的存储库模式(此示例不使用接口)。
[注意:代码无法编译,仅用于演示建议]
public class PositionProviderRepository
{
public 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));
}
}
public List<CustomerEntity> GetCustomersByUserPermission(Guid userId) {
//TODO: implementation
}
}
然后,在所有类(例如CustomerEntity)中使用此类。
这可以有效地替换您的类
SqlPositionProvider<T>
,但是我不确定我是否正确理解您的体系结构,因为您的体系结构非常复杂。关于c# - 需要一些帮助来解决DAL中的主要抽象模式头痛,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1661549/