EF object relational mapping met attributen
De namspaces die je hiervoor nodig hebt:
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema;
Table
Tenzij uitdrukkelijk ingesteld, wordt de tabel waarin een type entiteit wordt opgeslagen door conventie (meer hierover later) bepaald. Maar het is mogelijk om het type expliciet met een TableAttribute
aan te gevent.
[Table("Customers", Schema = "dbo")] public class Customer {}
De Schema
eigenschap is optioneel en moet alleen worden gebruikt om een schema op te geven waarvan de naam anders dan de standaardnaam. Een schema is een verzameling van de database-objecten (tabellen, views, opgeslagen procedures, functies, enz.) In dezelfde database. In SQL Server, de standaard schema is dbo.
Column
Voor het bepalen van hoe een eigenschap wordt opgeslagen (kolom naam, fysieke volgorde en het type database), gebruiken we een Column
attribuut.
[Column(Order = 3, TypeName = "NVARCHAR")] public string FirstName { get; set; } [Column(Order = 2, TypeName = "NVARCHAR")] public string LastName { get; set; }
Als de TypeName
niet is opgegeven, zal Entity Framework het standaardtype nemen dat overeen komt met het gegevenstype van de eigenschap. SQL Server zal NVARCHAR voor String
eigenschappen, INT voor Int32
, BIT voor Boolean
, enz. gebruiken. We kunnen TypeName
gebruiken om deze standaard te overschrijven.
De Order
past een fysieke volgorde toe op de gegenereerde kolommen die afwijkt van de volgorde waarin de eigenschappen in de klasse opgesomd zijn. Wanneer de eigenschap Order
wordt gebruikt, mogen er geen twee objecten met dezelfde waarde in dezelfde klasse zitten.
Een scalar eigenschap kan je markeren als vereist met het RequiredAttribute
attribuut.
[Required] public string PostalCode { get; set; }
Wanneer dit attribuut wordt toegepast op een string eigenschap, voorkomt het niet alleen dat de eigenschap null is, maar ook dat het een lege string is.
Voor een verplichte geassocieerde entiteit doe je precies hetzelfde
[Table("Orders")] public class Order { [Required] public virtual Customer Customer { get; set; } }
MaxLength
De maximale lengte van een string kolom kan ingesteld worden door middel van het MaxLength
attribuut.
In EF4.1 RTW is de standaardlengte nvarchar(max) voor SQL Server en nvarchar(4000) voor SQL CE.
[MaxLength(50)] public String Name { get; set; }
Het MaxLength
attribuut kan ook worden gebruikt om een kolom als een CLOB, een kolom die een grote hoeveelheid tekst, te definiëren. SQL Server maakt gebruik van de types NVARCHAR (MAX) en VARCHAR (MAX). Daarvoor, geven we een lengte van -1.
[MaxLength(-1)] public String Biography { get; set; }
Het kan ook worden gebruikt om de grootte van een BLOB kolom te definiëren (in SQL Server VARBINARY) .
[MaxLength(-1)] public Byte[] Picture { get; set; }
Net als in het vorige voorbeeld, wordt de grootte -1 effectief omgezet naar MAX.
NotMapped
Entity Framework negeert een eigenschap die gemarkeerd is met NotMapped.
[NotMapped] public String PropertyToBeIgnoredByEF { get; set; }
Je kan ook een volledige klasse laten negeren door EF.
[NotMapped] public class TBeIgnoredByEF { }
Key
In de database hebben tabellen strikt genomen geen primaire sleutel nodig. Maar in Entity Framework is een primary key vereist. Zowel één enkele kolom als meerdere kolommen (composite) kunnen als primaire sleutels worden gebruikt. Je markeert een eigenschap of eigenschappen als de primaire sleutel met het attribuut Key.
[Key] public Int32 ProductId { get; set; }
Als we een samengestelde primaire sleutel willen maken, moeten we ook een Column
attribuut gebruiken. Daarin moeten we expliciet de volgorde opgeven door middel van de eigenschap Order
zodat EF de volgorde kent van de kolommen in de samengestelde primaire sleutel.
[Key] [Column(Order = 1)] public string Voornaam { get; set; } [Key] [Column(Order = 2)] public string Familienaam { get; set; } [Key] [Column(Order = 3)] public datetime GeboorteDatum { get; set; }
DatabaseGenerated
Primaire sleutels kunnen ook worden versierd met een attribuut dat het Entity Framework vertelt hoe sleutels gegenereerd moeten worden, namelijk door de database of handmatig. Dit attribuut is eigenschap heet DatabaseGenerated
. Meer informatie hierover in het hoofdstuk Identifier Strategies.
ForeignKey
We hoeven meestal geen vreemde sleutels aan onze entiteiten toe te voegen. in plaats daarvan gebruiken we de verwijzingen naar de andere entiteit. Maar we kunnen foreign keys ook toevoegen met het ForeignKey
attribuut.
public virtual Customer Customer { get; set; }
of
[ForeignKey("Customer")] public Int32 CustomerId { get; set; }
DatabaseGenerated
Entity Framework Code First ondersteunt geen berekende kolommen (computed columns), kolommen waarvan de waarden berekend worden en niet fysiek zijn opgeslagen in een tabel, maar in plaats daarvan SQL-formules automatisch worden gegenereerd. Maar je kan het wel handmatig doen en toewijzen aan je entiteiten. Een typisch voorbeeld is het combineren van een voornaam en een achternaam in een volledige naam. Dat kan kan je op de SQL Server heel doen.
Je kan SQL server gegenereerde kolommen toewijzen aan een entiteit, maar je moet Entity Framework vertellen dat deze eigenschap niet moet worden geïnserted. Daarvoor gebruiken we de DatabaseGenerated
attribuut.
public virtual String FirstName { get; set; } public virtual String LastName { get; set; } [DatabaseGenerated(DatabaseGeneratedOption.Computed)] public virtual String FullName { get; protected set; }
Vermits de eigenschap nooit zal worden ingesteld, kunnen we de setter als een protected
methode declareren. Met de DatabaseGeneratedOption.Computed
eigenschap laten we Entity Framework weten dat het nooit moet proberen deze kolom te inserten of te updaten.
Op die manier kan je berekende eigenschap FullName
met zowel LINQ to Objects en LINQ to Entities opvragen.