我使自己的数据访问层出现了问题。在此特定实例中,我有一个表,其中可能包含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/

10-11 04:55