Como você lida com métodos de serviço em 2 tabelas sql muito semelhantes

Eu tenho 2 tabelas sql que são muito semelhantes. Apenas a chave estrangeira é diferente para cada tabela.

TemplateUnit table:

Id (PK)
ParentId
Name
TemplateId (FK)

TestplanUnit table:

Id (PK)
ParentId
Name
TestplanId (FK)

Quando eu vou para 2 tabelas que tem o mesmo conteúdo - apenas o FK é diferente - você realmente cria duplicatas de seus métodos CRUD em seu serviço e dataprovider (usando ado.net puro)?

Como o serviço seria aprimorado para que apenas um tipo de método Get/Add/Update/Delete seja usado na classe service e dataprovider? Eu também não quero fazer testes unitários duplicados ...

ATUALIZAR:

Esta é a minha solução até agora:

public class Unit
    {
        public string Name { get; set; }
        public int Id { get; set; }
        public Nullable ParentId { get; set; }
        public int TemplateId { get; set; }      
        public bool IsLazy { get; set; }         
    }



public class UnitDTO
    {
        public UnitDTO(UnitMode mode)
        {
            switch (mode)
            {
                case UnitMode.Template:
                    this.ForeinKeyName = "TemplateId";
                    this.TableName = "TemplateUnit";
                    break;
                case UnitMode.Testplan:
                    this.ForeinKeyName = "TestplanId";
                    this.TableName = "TestplanUnit";
                    break;
            }

            UnitBO = new Unit();
        }

        public string TableName { get; private set; }        
        public string ForeinKeyName { get; private set; }
        public Unit UnitBO { get; private set; }
    }

    public enum UnitMode
    {
        Template = 0,
        Testplan = 1,
    }

Meus métodos Get/Add/Delete em BLL e DAL obtêm um objeto UnitDTO com todas as informações necessárias.

Bem, uma desvantagem poderia ser - se este projeto fosse feito em uma equipe - que você tem que saber qual variável é usada/necessária no DAL quando você cria o UnitDTO e passa para o BLL para cada método CRUD.

O que você acha?

0
adicionado editado
Visualizações: 1

2 Respostas

Eu acho que seria melhor se você especificasse explicitamente seu tipo como as etapas a seguir.

public enum TableTypeEnum
{
    Template =0,
    TestPlan =1
}

public abstract class UnitBase
{   
    public int Id { get; set; }
    public Nullable ParentId { get; set; }
    public string Name { get; set; }

    public TableTypeEnum TableType { get; private set; }


    protected UnitBase(TableTypeEnum  type)
    {
        TableType = type;
    }
}

public class TemplateUnit:UnitBase
{
    public int TemplateForeignKeyId { get; set; }
    public TemplateUnit() : base(TableTypeEnum.Template)
    {}
}

public class TestPlanUnit:UnitBase
{
    public Guid TestplanForeignKeyId { get; set; }
    public TestPlanUnit():base(TableTypeEnum.TestPlan)
    {}
}

e a classe DAL pode ser assim

public class  DAL
    {
        public void Insert(UnitBase unit)
        {
            switch (unit.TableType)
            {
                case  TableTypeEnum.Template:
                    //insert into the template table
                    break;
                case TableTypeEnum.TestPlan:
                     //insert into the testplan table
                    break;
            }
        }

    }

Ao fazer isso, quando outras pessoas chamam seu código, elas sabem exatamente com qual tipo de unidade estão trabalhando e você pode evitar a duplicação de seu código. Espero que esta ajuda.

0
adicionado
Você mudou o DAL. Então, meu BLL (UnitService) ainda tem os mesmos métodos para 2 tabelas diferentes. As unidades de um modelo serão sempre as mesmas da unidade de um plano de teste, porque a unidade testplan é uma cópia/backup da unidade de modelos. Então a chamada de uma classe de controlador asp.net mvc seria unitService.Insert (unit)?
adicionado o autor Elisabeth, fonte

Ok, vou sugerir que você não combine as operações CRUD. Por que a unidade pode ser armazenada em duas tabelas? Deve haver algum tipo de regra no seu domínio que determina em qual tabela armazená-lo? Esta "regra" é uma indicação de que sua Unidade pode ter mais de um significado/definição/especificação, por menor que seja. No momento em que uma dessas especificações mudar (talvez uma coluna adicional, etc.), você ficará com um conjunto de operações CRUD que ficarão sujas por declarações condicionais, e isso pode ficar complicado.

Se houver uma diferença fundamental entre as duas unidades, eu diria até criar objetos de negócios separados, com suas próprias regras. Mantenha seu design puro, mantenha-o separado. Sim, é mais código, mas é mais simples.

0
adicionado
não é mais código, será sempre um código duplicado. Se eu mudar um testplanUnitService eu tenho que mudar o outro também. Ambas as tabelas salvam os mesmos dados, a diferença é apenas a chave estrangeira. A tabela de uma unidade armazena as unidades do modelo. Os planos de teste fazem uma cópia de todas as unidades de um modelo, mas armazenadas na outra tabela de unidades por causa da outra chave estrangeira.
adicionado o autor Elisabeth, fonte