O ID do objeto de negócios deve ser somente leitura ou não?
-
12-09-2019 - |
Pergunta
Na minha opinião, o campo de identificação de um objeto de negócios deve ser somente leitura (o conjunto público e privado), pois, por definição, o ID nunca mudará (pois identifica exclusivamente um registro no banco de dados).
Isso cria um problema quando você cria um novo objeto (ID ainda não definido), salve -o no banco de dados por meio de um procedimento armazenado, por exemplo, que retorna o ID recém -criado, como você o armazena novamente se a propriedade ID for lida -só?
Exemplo:
Employee employee = new Employee();
employee.FirstName="John";
employee.LastName="Smith";
EmployeeDAL.Save(employee);
Como o método SALVE (que realmente se conecta ao banco de dados para salvar o novo funcionário) atualiza a propriedade do EmployeeID no objeto do funcionário se essa propriedade for somente leitura (que deve ser como o Funcionário nunca mudará depois de criar).
Parece que o ID deve ser gravável pelo DAL e somente leitura para o resto do mundo. Como você implementa isso, especialmente se as classes da DAL e os objetos de negócios estiverem em diferentes montagens?
Não quero criar um método salvo na classe dos funcionários, pois essa classe não deve ter nada a ver com o banco de dados.
Solução
Outra solução possível é declarar funcionário como:-
public class Employee
{
public int Id { get; internal set; }
}
... desde que o funcionário e as aulas de DAL estejam na mesma assembléia
Não afirmo gostar, mas usei.
Outras dicas
Você pode fazer com que seu método DAL basta retornar um objeto atualizado:
public class EmployeeDAL
{
Employee EmployeeDAL.Save (Employee employee)
{
// Save employee
// Get the newly generated ID
// Recreate the object with the new ID and return it
}
}
Como alternativa, você pode gerar um novo ID no código, instanciar um objeto com esse ID e solicitar seu dal para salvá -lo.
Se você deseja que seu objeto tenha sido atualizado durante a operação de salvamento, você terá que tornar essa propriedade pública.
Eu pessoalmente gosto de criar imutável Objetos, aqueles que você só pode configurar uma vez passando todos os valores para o construtor. Com essa abordagem, você apenas criaria um objeto a ser salvo e, em seguida, recuperá -lo junto com o ID atribuído do banco de dados e o devolva ao chamador.
Você pode fazer o seu setter para o ID permitir o conjunto apenas se ele ainda não tivesse sido definido antes:
public class Employee
{
private int? m_ID;
public int? ID
{
get { return m_ID; }
set
{
if (m_ID.HasValue())
throw ...
m_ID = value;
}
}
}
Como alternativa, acho que algumas estruturas suportam esse tipo de funcionalidade (por exemplo, acho que o Nibernate permitirá que você tenha um setter privado em um campo de identificação).
Que tal permitir apenas o código fora do DAL, consulte o objeto através de uma interface que não fornece um setter para o campo de identificação (e quaisquer outros campos imutáveis):
public interface IEmployee
{
Int32 Id {get;}
String Name {get;set;}
// ... and so on ...
}
public class Employee: IEmployee
{
Int32 Id {get;set;}
String Name {get;set;}
}
O DAL pode defini -lo conforme necessário, mas o código de consumo não pode.
Que tal:
Employee employee = new Employee(EmployeeDAL.GetNextID());
Isso também deve simplificar seu código SAVE.