Como: Mapear relações de banco de dados
Você pode codificar como referências de propriedade em sua classe de entidade quaisquer relações de dados que serão sempre as mesmas. No banco de dados de exemplo Northwind, por exemplo, como os clientes normalmente fazem pedidos, há sempre uma relação no modelo entre os clientes e seus pedidos.
LINQ to SQL define um AssociationAttribute atributo para ajudar a representar essas relações. Esse atributo é usado junto com os EntitySet<TEntity> tipos e EntityRef<TEntity> para representar o que seria uma relação de chave estrangeira em um banco de dados. Para obter mais informações, consulte a seção Atributo de associação do mapeamento baseado em atributos.
Nota
Os valores das propriedades AssociationAttribute e ColumnAttribute Storage diferenciam maiúsculas de minúsculas. Por exemplo, certifique-se de que os valores usados no atributo para a propriedade AssociationAttribute.Storage correspondam ao caso dos nomes de propriedade correspondentes usados em outro lugar no código. Isso se aplica a todas as linguagens de programação .NET, mesmo aquelas que normalmente não diferenciam maiúsculas de minúsculas, incluindo o Visual Basic. Para obter mais informações sobre a propriedade Storage, consulte DataAttribute.Storage.
A maioria dos relacionamentos são um-para-muitos, como no exemplo mais adiante neste tópico. Você também pode representar relações um-para-um e muitos-para-muitos da seguinte maneira:
Um-para-um: Represente este tipo de relação incluindo EntitySet<TEntity> em ambos os lados.
Por exemplo, considere uma
Customer
-SecurityCode
relação, criada para que o código de segurança do cliente não seja encontrado na tabela e possa ser acessadoCustomer
apenas por pessoas autorizadas.Muitos-para-muitos: Em relações muitos-para-muitos, a chave primária da tabela de links (também chamada de tabela de junção ) é frequentemente formada por uma composição das chaves estrangeiras das outras duas tabelas.
Por exemplo, considere uma
Employee
-Project
relação muitos-para-muitos formada usando a tabelaEmployeeProject
de links. O LINQ to SQL requer que essa relação seja modelada usando três classes:Employee
,Project
eEmployeeProject
. Nesse caso, alterar a relação entre umEmployee
e umProject
pode parecer exigir uma atualização da chaveEmployeeProject
primária. No entanto, essa situação é melhor modelada como a exclusão de um existenteEmployeeProject
e a criação de um novoEmployeeProject
.Nota
As relações em bancos de dados relacionais são normalmente modeladas como valores de chave estrangeira que se referem a chaves primárias em outras tabelas. Para navegar entre elas, associe explicitamente as duas tabelas usando uma operação de junção relacional.
Os objetos no LINQ to SQL, por outro lado, referem-se uns aos outros usando referências de propriedade ou coleções de referências que você navega usando notação de ponto .
Exemplo 1
No exemplo um-para-muitos a seguir, a Customer
classe tem uma propriedade que declara a relação entre os clientes e seus pedidos. A Orders
propriedade é do tipo EntitySet<TEntity>. Este tipo significa que esta relação é um-para-muitos (um cliente para muitas encomendas). A OtherKey propriedade é usada para descrever como essa associação é realizada, ou seja, especificando o nome da propriedade na classe relacionada a ser comparada com esta. Neste exemplo, a CustomerID
propriedade é comparada, assim como uma associação de banco de dados compararia esse valor de coluna.
Nota
Se você estiver usando o Visual Studio, você pode usar o Object Relational Designer para criar uma associação entre classes.
[Table(Name = "Customers")]
public partial class Customer
{
[Column(IsPrimaryKey = true)]
public string CustomerID;
// ...
private EntitySet<Order> _Orders;
[Association(Storage = "_Orders", OtherKey = "CustomerID")]
public EntitySet<Order> Orders
{
get { return this._Orders; }
set { this._Orders.Assign(value); }
}
}
<Table(Name:="Customers")> _
Public Class Customer
<Column(IsPrimaryKey:=True)> _
Public CustomerID As String
' ...
Private _Orders As EntitySet(Of Order)
<Association(Storage:="_Orders", OtherKey:="CustomerID")> _
Public Property Orders() As EntitySet(Of Order)
Get
Return Me._Orders
End Get
Set(ByVal value As EntitySet(Of Order))
Me._Orders.Assign(value)
End Set
End Property
End Class
Exemplo 2
Você também pode reverter a situação. Em vez de usar a Customer
classe para descrever a associação entre clientes e pedidos, você pode usar a Order
classe. A Order
classe usa o EntityRef<TEntity> tipo para descrever o relacionamento de volta para o cliente, como no exemplo de código a seguir.
Nota
A EntityRef<TEntity> classe suporta carregamento diferido. Para obter mais informações, consulte Carregamento adiado versus imediato.
[Table(Name = "Orders")]
public class Order
{
[Column(IsPrimaryKey = true)]
public int OrderID;
[Column]
public string CustomerID;
private EntityRef<Customer> _Customer;
[Association(Storage = "_Customer", ThisKey = "CustomerID")]
public Customer Customer
{
get { return this._Customer.Entity; }
set { this._Customer.Entity = value; }
}
}
<Table(Name:="Orders")> _
Public Class Order
<Column(IsPrimaryKey:=True)> _
Public OrderID As Integer
<Column()> _
Public CustomerID As String
Private _Customer As EntityRef(Of Customer)
<Association(Storage:="Customer", ThisKey:="CustomerID")> _
Public Property Customer() As Customer
Get
Return Me._Customer.Entity
End Get
Set(ByVal value As Customer)
Me._Customer.Entity = value
End Set
End Property
End Class