Postupy: Mapování relací databáze
Jako odkazy na vlastnosti ve třídě entity můžete zakódovat všechny relace dat, které budou vždy stejné. Například v ukázkové databázi Northwind, protože zákazníci obvykle zavádějí objednávky, existuje v modelu vždy vztah mezi zákazníky a jejich objednávkami.
LINQ to SQL definuje AssociationAttribute atribut, který pomáhá reprezentovat takové relace. Tento atribut se používá společně s EntitySet<TEntity> EntityRef<TEntity> typy, které představují vztah cizího klíče v databázi. Další informace naleznete v části Atribut přidružení mapování na základě atributů.
Poznámka:
Hodnoty vlastností AssociationAttribute a ColumnAttribute Storage rozlišují malá a velká písmena. Ujistěte se například, že hodnoty použité v atributu pro AssociationAttribute.Storage vlastnost odpovídají případu odpovídajících názvů vlastností použitých jinde v kódu. To platí pro všechny programovací jazyky .NET, i ty, které obvykle nerozlišují velká a malá písmena, včetně jazyka Visual Basic. Další informace o vlastnosti Storage naleznete v tématu DataAttribute.Storage.
Většina relací je 1:N, stejně jako v příkladu dále v tomto tématu. Relace 1:1 a M:N můžete znázorňovat následujícím způsobem:
1:1: Tento druh vztahu představuje zahrnutím EntitySet<TEntity> obou stran.
Představte si například relaci vytvořenou
Customer
-SecurityCode
tak, aby bezpečnostní kód zákazníka nebyl vCustomer
tabulce nalezen a byl přístupný pouze oprávněnými osobami.M:N: V relacích M:N se primární klíč tabulky propojení (označované také jako spojovací tabulka) často vytváří složenou z cizích klíčů z ostatních dvou tabulek.
Představte si například relaci M:N vytvořenou
Employee
-Project
pomocí tabulkyEmployeeProject
propojení . LINQ to SQL vyžaduje, aby byl takový vztah modelován pomocí tří tříd:Employee
,Project
aEmployeeProject
. V tomto případě se může zdát, že změna vztahu mezi aEmployee
aProject
může vyžadovat aktualizaci primárního klíčeEmployeeProject
. Tato situace je však nejvhodnější modelovat jako odstranění existujícíhoEmployeeProject
a vytvoření novéhoEmployeeProject
.Poznámka:
Relace v relačních databázích se obvykle modelují jako hodnoty cizího klíče, které odkazují na primární klíče v jiných tabulkách. K navigaci mezi nimi explicitně přidružíte dvě tabulky pomocí operace relačního spojení .
Objekty v LINQ to SQL se na druhé straně vzájemně odkazují pomocí odkazů na vlastnosti nebo kolekcí odkazů, které procházíte pomocí tečkované notace.
Příklad 1
V následujícím příkladu Customer
1:N má třída vlastnost, která deklaruje vztah mezi zákazníky a jejich objednávkami. Vlastnost Orders
je typu EntitySet<TEntity>. Tento typ označuje, že tento vztah je 1:N (jeden zákazník k mnoha objednávkám). Vlastnost OtherKey slouží k popisu, jak se toto přidružení provádí, konkrétně zadáním názvu vlastnosti v související třídě, která má být porovnána s touto. V tomto příkladu CustomerID
se tato vlastnost porovnává stejně jako spojení databáze s touto hodnotou sloupce.
Poznámka:
Pokud používáte Visual Studio, můžete pomocí Návrhář relací objektů vytvořit přidružení mezi třídami.
[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
Příklad 2
Situaci můžete také vrátit zpět. Místo použití Customer
třídy k popisu přidružení mezi zákazníky a objednávkami můžete třídu použít Order
. Třída Order
používá EntityRef<TEntity> typ k popisu vztahu zpět k zákazníkovi, jako v následujícím příkladu kódu.
Poznámka:
Třída EntityRef<TEntity> podporuje odložené načítání. Další informace naleznete v tématu Deferred versus Okamžité načítání.
[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