Modello a oggetti LINQ to SQL
In LINQ to SQL, un modello a oggetti espresso nel linguaggio di programmazione dello sviluppatore viene mappato al modello dati di un database relazionale. Le operazioni sui dati vengono quindi eseguite in base al modello a oggetti.
In questo scenario non vengono eseguiti comandi di database, ad esempio INSERT
, sul database, bensì vengono modificati valori ed eseguiti metodi all'interno del modello a oggetti. Quando si vuole eseguire una query sul database o inviare modifiche al database, LINQ to SQL converte le richieste in comandi SQL corretti che vengono quindi inviati al database.
Nella tabella seguente sono riepilogati gli elementi più importanti nel modello a oggetti di LINQ to SQL e le relative relazioni con gli elementi nel modello dati relazionale:
Modello a oggetti LINQ to SQL | Modello dati relazionale |
---|---|
Classe di entità | Tabella |
Membro di classe | Istogramma |
Associazione | Relazione di chiave esterna |
metodo | Stored procedure o funzione |
Nota
Nelle descrizioni seguenti si presuppone una conoscenza di base del modello dati relazionale e delle regole.
Classi di entità LINQ to SQL e tabelle di database
In LINQ to SQL una tabella di database è rappresentata da una classe di entità. Una classe di entità è analoga a qualsiasi altra classe creata dallo sviluppatore, con l'eccezione che per annotare la classe vengono usate informazioni speciali che associano la classe a una tabella di database. Per creare tale annotazione, aggiungere un attributo personalizzato (TableAttribute) alla dichiarazione della classe, come nell'esempio seguente:
Esempio
[Table(Name = "Customers")]
public class Customerzz
{
public string CustomerID;
// ...
public string City;
}
<Table(Name:="Customers")> _
Public Class Customer
Public CustomerID As String
' ...
Public City As String
End Class
Solo le istanze delle classi dichiarate come tabelle, ovvero le classi di entità, possono essere salvate nel database.
Per altre informazioni, vedere la sezione relativa all'attributo Table in Mapping basato su attributi.
Membri di classe LINQ to SQL e colonne di database
Oltre all'associazione delle classi con le tabelle, è necessario definire i campi o le proprietà per rappresentare le colonne del database. A questo scopo in LINQ to SQL viene definito l'attributo ColumnAttribute, come nell'esempio seguente:
Esempio
[Table(Name = "Customers")]
public class Customer
{
[Column(IsPrimaryKey = true)]
public string CustomerID;
[Column]
public string City;
}
<Table(Name:="Customers")> _
Public Class Customer
<Column(IsPrimaryKey:=True)> _
Public CustomerID As String
<Column()> _
Public City As String
End Class
Solo i campi e le proprietà di cui è stato eseguito il mapping alle colonne vengono salvati in modo permanente o recuperati dal database. Quelli non dichiarati come colonne vengono considerati parti temporanee della logica dell'applicazione.
All'attributo ColumnAttribute sono associate diverse proprietà che è possibile usare per personalizzare i membri che rappresentano colonne, ad esempio definendo un membro che rappresenta una colonna di chiave primaria. Per altre informazioni, vedere la sezione relativa all'attributo Column in Mapping basato su attributi.
Associazioni LINQ to SQL e relazioni di chiave esterna del database
In LINQ to SQL per rappresentare associazioni di database, ad esempio relazioni da chiave esterna a chiave primaria, viene applicato l'attributo AssociationAttribute. Nel segmento di codice seguente la classe Order
contiene una proprietà Customer
con un attributo AssociationAttribute. Questa proprietà e il relativo attributo forniscono la classe Order
con una relazione alla classe Customer
.
Nell'esempio di codice riportato di seguito viene illustrata la proprietà Customer
della classe Order
.
Esempio
[Association(Name="FK_Orders_Customers", Storage="_Customer", ThisKey="CustomerID", IsForeignKey=true)]
public Customer Customer
{
get
{
return this._Customer.Entity;
}
set
{
Customer previousValue = this._Customer.Entity;
if (((previousValue != value)
|| (this._Customer.HasLoadedOrAssignedValue == false)))
{
this.SendPropertyChanging();
if ((previousValue != null))
{
this._Customer.Entity = null;
previousValue.Orders.Remove(this);
}
this._Customer.Entity = value;
if ((value != null))
{
value.Orders.Add(this);
this._CustomerID = value.CustomerID;
}
else
{
this._CustomerID = default(string);
}
this.SendPropertyChanged("Customer");
}
}
}
<Association(Name:="FK_Orders_Customers", Storage:="_Customer", ThisKey:="CustomerID", IsForeignKey:=true)> _
Public Property Customer() As Customer
Get
Return Me._Customer.Entity
End Get
Set
Dim previousValue As Customer = Me._Customer.Entity
If (((previousValue Is value) _
= false) _
OrElse (Me._Customer.HasLoadedOrAssignedValue = false)) Then
Me.SendPropertyChanging
If ((previousValue Is Nothing) _
= false) Then
Me._Customer.Entity = Nothing
previousValue.Orders.Remove(Me)
End If
Me._Customer.Entity = value
If ((value Is Nothing) _
= false) Then
value.Orders.Add(Me)
Me._CustomerID = value.CustomerID
Else
Me._CustomerID = CType(Nothing, String)
End If
Me.SendPropertyChanged("Customer")
End If
End Set
End Property
Per altre informazioni, vedere la sezione relativa all'attributo Association di Mapping basato su attributi.
Metodi LINQ to SQL e stored procedure di database
LINQ to SQL supporta stored procedure e funzioni definite dall'utente. In LINQ to SQL viene eseguito il mapping di queste astrazioni definite dal database agli oggetti client, in modo che sia possibile accedervi in modo fortemente tipizzato dal codice client. Le firme del metodo sono quanto più possibile simili alle firme delle procedure e delle funzioni definite nel database. Per individuare questi metodi è possibile usare IntelliSense.
Un set di risultati restituito da una chiamata a una procedura con mapping è una raccolta fortemente tipizzata.
LINQ to SQL esegue il mapping di stored procedure e funzioni ai metodi usando gli attributi FunctionAttribute e ParameterAttribute. I metodi che rappresentano stored procedure si differenziano da quelli che rappresentano funzioni definite dall'utente per la proprietà IsComposable. Se questa proprietà è impostata su false
, che corrisponde all'impostazione predefinita, il metodo rappresenta una stored procedure. Se è impostata su true
, il metodo rappresenta una funzione di database.
Nota
Se si usa Visual Studio, è possibile usare Object Relational Designer per creare metodi mappati a stored procedure e funzioni definite dall'utente.
Esempio
// This is an example of a stored procedure in the Northwind
// sample database. The IsComposable property defaults to false.
[Function(Name="dbo.CustOrderHist")]
public ISingleResult<CustOrderHistResult> CustOrderHist([Parameter(Name="CustomerID", DbType="NChar(5)")] string customerID)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), customerID);
return ((ISingleResult<CustOrderHistResult>)(result.ReturnValue));
}
' This is an example of a stored procedure in the Northwind
' sample database. The IsComposable property defaults to false.
<FunctionAttribute(Name:="dbo.CustOrderHist")> _
Public Function CustOrderHist(<Parameter(Name:="CustomerID", DbType:="NChar(5)")> ByVal customerID As String) As ISingleResult(Of CustOrderHistResult)
Dim result As IExecuteResult = Me.ExecuteMethodCall(Me, CType(MethodInfo.GetCurrentMethod, MethodInfo), customerID)
Return CType(result.ReturnValue, ISingleResult(Of CustOrderHistResult))
End Function
Per altre informazioni, vedere le sezioni relative agli attributi Function, Stored Procedure e Parameter in Mapping basato su attributi e Stored procedure.