Implementando lógica de negócios (LINQ to SQL)
O termo "lógica de negócios" neste tópico refere-se a quaisquer regras personalizadas ou testes de validação que você aplica aos dados antes que eles sejam inseridos, atualizados ou excluídos do banco de dados. A lógica de negócios também é às vezes referida como "regras de negócios" ou "lógica de domínio". Em aplicativos de n camadas, ele é normalmente projetado como uma camada lógica para que possa ser modificado independentemente da camada de apresentação ou da camada de acesso a dados. A lógica de negócios pode ser invocada pela camada de acesso a dados antes ou depois de qualquer atualização, inserção ou exclusão de dados no banco de dados.
A lógica de negócios pode ser tão simples quanto uma validação de esquema para garantir que o tipo do campo seja compatível com o tipo de coluna da tabela. Ou pode consistir em um conjunto de objetos que interagem de maneiras arbitrariamente complexas. As regras podem ser implementadas como procedimentos armazenados no banco de dados ou como objetos na memória. No entanto a lógica de negócios é implementada, o LINQ to SQL permite que você use classes parciais e métodos parciais para separar a lógica de negócios do código de acesso a dados.
Como o LINQ to SQL invoca sua lógica de negócios
Quando você gera uma classe de entidade em tempo de design, manualmente ou usando o Object Relational Designer ou SQLMetal, ela é definida como uma classe parcial. Isso significa que, em um arquivo de código separado, você pode definir outra parte da classe de entidade que contém sua lógica de negócios personalizada. Em tempo de compilação, as duas partes são fundidas em uma única classe. Mas se você tiver que regenerar suas classes de entidade usando o Object Relational Designer ou SQLMetal, você pode fazer isso e sua parte da classe não será modificada.
As classes parciais que definem entidades e contêm DataContext métodos parciais. Esses são os pontos de extensibilidade que você pode usar para aplicar sua lógica de negócios antes e depois de qualquer atualização, inserção ou exclusão de uma entidade ou propriedade de entidade. Métodos parciais podem ser pensados como eventos em tempo de compilação. O gerador de código define uma assinatura de método e chama os métodos nos acessadores de propriedade get e set, o DataContext
construtor e, em alguns casos, nos bastidores quando SubmitChanges é chamado. No entanto, se você não implementar um método parcial específico, todas as referências a ele e a definição serão removidas em tempo de compilação.
Na definição de implementação que você escreve em seu arquivo de código separado, você pode executar qualquer lógica personalizada necessária. Você pode usar sua própria classe parcial como sua camada de domínio, ou você pode chamar a partir de sua definição de implementação do método parcial para um objeto ou objetos separados. De qualquer forma, sua lógica de negócios é claramente separada do código de acesso a dados e do código da camada de apresentação.
Um olhar mais atento sobre os pontos de extensibilidade
O exemplo a seguir mostra parte do código gerado pelo Object Relational Designer para a DataContext
classe que tem duas tabelas: Customers
e Orders
. Observe que os métodos Insert, Update e Delete são definidos para cada tabela na classe.
Partial Public Class Northwnd
Inherits System.Data.Linq.DataContext
Private Shared mappingSource As _
System.Data.Linq.Mapping.MappingSource = New _
AttributeMappingSource
#Region "Extensibility Method Definitions"
Partial Private Sub OnCreated()
End Sub
Partial Private Sub InsertCustomer(instance As Customer)
End Sub
Partial Private Sub UpdateCustomer(instance As Customer)
End Sub
Partial Private Sub DeleteCustomer(instance As Customer)
End Sub
Partial Private Sub InsertOrder(instance As [Order])
End Sub
Partial Private Sub UpdateOrder(instance As [Order])
End Sub
Partial Private Sub DeleteOrder(instance As [Order])
End Sub
#End Region
public partial class MyNorthWindDataContext : System.Data.Linq.DataContext
{
private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
#region Extensibility Method Definitions
partial void OnCreated();
partial void InsertCustomer(Customer instance);
partial void UpdateCustomer(Customer instance);
partial void DeleteCustomer(Customer instance);
partial void InsertOrder(Order instance);
partial void UpdateOrder(Order instance);
partial void DeleteOrder(Order instance);
#endregion
Se você implementar os métodos Insert, Update e Delete em sua classe parcial, o tempo de execução do LINQ to SQL os chamará em vez de seus próprios métodos padrão quando SubmitChanges for chamado. Isso permite que você substitua o comportamento padrão para operações de criação / leitura / atualização / exclusão. Para obter mais informações, consulte Passo a passo: Personalizando o comportamento de inserção, atualização e exclusão de classes de entidade.
O OnCreated
método é chamado no construtor de classe.
Public Sub New(ByVal connection As String)
MyBase.New(connection, mappingSource)
OnCreated()
End Sub
public MyNorthWindDataContext(string connection) :
base(connection, mappingSource)
{
OnCreated();
}
As classes de entidade têm três métodos que são chamados pelo tempo de execução do LINQ to SQL quando a entidade é criada, carregada e validada (quando SubmitChanges
é chamada). As classes de entidade também têm dois métodos parciais para cada propriedade, um que é chamado antes da propriedade ser definida e outro que é chamado depois. O exemplo de código a seguir mostra alguns dos métodos gerados para a Customer
classe:
#Region "Extensibility Method Definitions"
Partial Private Sub OnLoaded()
End Sub
Partial Private Sub OnValidate(action As _
System.Data.Linq.ChangeAction)
End Sub
Partial Private Sub OnCreated()
End Sub
Partial Private Sub OnCustomerIDChanging(value As String)
End Sub
Partial Private Sub OnCustomerIDChanged()
End Sub
Partial Private Sub OnCompanyNameChanging(value As String)
End Sub
Partial Private Sub OnCompanyNameChanged()
End Sub
' ...Additional Changing/Changed methods for each property.
#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate();
partial void OnCreated();
partial void OnCustomerIDChanging(string value);
partial void OnCustomerIDChanged();
partial void OnCompanyNameChanging(string value);
partial void OnCompanyNameChanged();
// ...additional Changing/Changed methods for each property
Os métodos são chamados no acessador do conjunto de propriedades, conforme mostrado no exemplo a seguir para a CustomerID
propriedade:
Public Property CustomerID() As String
Set
If (String.Equals(Me._CustomerID, value) = False) Then
Me.OnCustomerIDChanging(value)
Me.SendPropertyChanging()
Me._CustomerID = value
Me.SendPropertyChanged("CustomerID")
Me.OnCustomerIDChanged()
End If
End Set
End Property
public string CustomerID
{
set
{
if ((this._CustomerID != value))
{
this.OnCustomerIDChanging(value);
this.SendPropertyChanging();
this._CustomerID = value;
this.SendPropertyChanged("CustomerID");
this.OnCustomerIDChanged();
}
}
}
Na sua parte da classe, você escreve uma definição de implementação do método. No Visual Studio, depois de digitar partial
, você verá IntelliSense para as definições de método na outra parte da classe.
Partial Public Class Customer
Private Sub OnCustomerIDChanging(value As String)
' Perform custom validation logic here.
End Sub
End Class
partial class Customer
{
partial void OnCustomerIDChanging(string value)
{
//Perform custom validation logic here.
}
}
Para obter mais informações sobre como adicionar lógica de negócios ao seu aplicativo usando métodos parciais, consulte os seguintes tópicos:
Como: Adicionar validação a classes de entidade
Passo a passo: Adicionando validação a classes de entidade