Share via


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 acessado Customer 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 tabela EmployeeProjectde links. O LINQ to SQL requer que essa relação seja modelada usando três classes: Employee, Projecte EmployeeProject. Nesse caso, alterar a relação entre um Employee e um Project pode parecer exigir uma atualização da chave EmployeeProjectprimária. No entanto, essa situação é melhor modelada como a exclusão de um existente EmployeeProject e a criação de um novo EmployeeProject.

    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, consulteCarregamento 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

Consulte também