Zoeken…


Opmerkingen

Entity Framework Code-First biedt een set DataAnnotation-attributen die u kunt toepassen op uw domeinklassen en eigenschappen. DataAnnotation-kenmerken hebben voorrang op standaard Code-First-conventies.

  1. System.ComponentModel.DataAnnotations bevat attributen die van invloed zijn op de nullabiliteit of de grootte van de kolom.
  2. System.ComponentModel.DataAnnotations.Schema- naamruimte bevat kenmerken die van invloed zijn op het schema van de database.

Opmerking: DataAnnotations geven u slechts een subset van configuratie-opties. Fluent API biedt een volledige set configuratie-opties beschikbaar in Code-First.

[Key] attribuut

Sleutel is een veld in een tabel dat elke rij / record in een databasetabel uniek identificeert.

Gebruik dit kenmerk om de standaard Code-First-conventie te overschrijven . Indien toegepast op een eigenschap, wordt deze gebruikt als de primaire sleutelkolom voor deze klasse.

using System.ComponentModel.DataAnnotations;

public class Person
{
    [Key]
    public int PersonKey { get; set; }        // <- will be used as primary key
     
    public string PersonName { get; set; }    
}

Als een samengestelde primaire sleutel vereist is, kan het kenmerk [Sleutel] ook aan meerdere eigenschappen worden toegevoegd. De volgorde van de kolommen in de samengestelde sleutel moet worden opgegeven in de vorm [ Key, Column (Order = x)] .

using System.ComponentModel.DataAnnotations;

public class Person
{
    [Key, Column(Order = 0)]
    public int PersonKey1 { get; set; }    // <- will be used as part of the primary key

    [Key, Column(Order = 1)]
    public int PersonKey2 { get; set; }    // <- will be used as part of the primary key
     
    public string PersonName { get; set; }    
}

Zonder het kenmerk [Key] valt EntityFramework terug naar de standaardconventie, namelijk het gebruik van de eigenschap van de klasse als een primaire sleutel met de naam "Id" of "{ClassName} Id".

public class Person
{
    public int PersonID { get; set; }        // <- will be used as primary key
     
    public string PersonName { get; set; }    
}

[Vereist] kenmerk

Wanneer toegepast op een eigenschap van een domeinklasse, maakt de database een NIET-NULL-kolom.

using System.ComponentModel.DataAnnotations;

public class Person
{
    public int PersonID { get; set; }
    
    [Required]
    public string PersonName { get; set; }    
}

De resulterende kolom met de beperking NOT NULL:

De resulterende kolom in een SQL Server

Opmerking: het kan ook worden gebruikt met asp.net-mvc als validatiekenmerk.

[MaxLength] en [MinLength] attributen

[MaxLength (int)] attribuut kan worden toegepast op een string of array type eigenschap van een domeinklasse. Entity Framework stelt de grootte van een kolom in op de opgegeven waarde.

using System.ComponentModel.DataAnnotations;

public class Person
{
    public int PersonID { get; set; }
    
    [MinLength(3), MaxLength(100)]
    public string PersonName { get; set; }    
}

De resulterende kolom met de opgegeven kolomlengte:

voer hier de afbeeldingsbeschrijving in

[MinLength (int)] -kenmerk is een validatiekenmerk, dit heeft geen invloed op de databasestructuur. Als we proberen een persoon met PersonName met een lengte van minder dan 3 tekens in te voegen / bij te werken, zal deze commit mislukken. We krijgen een DbUpdateConcurrencyException die we moeten afhandelen.

using (var db = new ApplicationDbContext())
{                    
     db.Staff.Add(new Person() { PersonName = "ng" });
     try
     {
          db.SaveChanges();
     }
     catch (DbEntityValidationException ex)
     {
          //ErrorMessage = "The field PersonName must be a string or array type with a minimum length of '3'."
     }
}

Zowel de kenmerken [MaxLength ] als [MinLength] kunnen ook worden gebruikt met asp.net-mvc als validatiekenmerk.

[Bereik (min, max)] attribuut

Specificeert een numeriek minimum en maximum bereik voor een eigenschap

using System.ComponentModel.DataAnnotations;   

public partial class Enrollment
{
    public int EnrollmentID { get; set; }
   
    [Range(0, 4)]
    public Nullable<decimal> Grade { get; set; }
}

Als we proberen een cijfer met een waarde buiten bereik in te voegen / bij te werken, zal deze commit mislukken. We krijgen een DbUpdateConcurrencyException die we moeten afhandelen.

using (var db = new ApplicationDbContext())
{
    db.Enrollments.Add(new Enrollment() { Grade = 1000 });

    try
    {
        db.SaveChanges();
    }
    catch (DbEntityValidationException ex)
    {
        // Validation failed for one or more entities
    }
}

Het kan ook worden gebruikt met asp.net-mvc als validatiekenmerk.

Resultaat:

voer hier de afbeeldingsbeschrijving in

[DatabaseGenerated] -kenmerk

Geeft aan hoe de database waarden genereert voor de eigenschap. Er zijn drie mogelijke waarden:

  1. None geeft aan dat de waarden niet door de database worden gegenereerd.
  2. Identity geeft aan dat de kolom een identiteitskolom is , die meestal wordt gebruikt voor primaire sleutels met gehele getallen.
  3. Computed geeft aan dat de database de waarde voor de kolom genereert.

Als de waarde iets anders is dan None , zal Entity Framework geen wijzigingen in de eigenschap doorvoeren aan de database.

Standaard (op basis van de StoreGeneratedIdentityKeyConvention ) wordt een sleutel met een geheel getal behandeld als een identiteitskolom. Als u deze conventie wilt negeren en wilt afdwingen dat deze als een niet-identiteitskolom moet worden behandeld, kunt u het kenmerk DatabaseGenerated met de waarde None .

using System.ComponentModel.DataAnnotations.Schema;

public class Foo
{
    [Key]
    public int Id { get; set; } // identity (auto-increment) column
}

public class Bar
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; } // non-identity column
}

De volgende SQL maakt een tabel met een berekende kolom:

CREATE TABLE [Person] (
    Name varchar(100) PRIMARY KEY,
    DateOfBirth Date NOT NULL,
    Age AS DATEDIFF(year, DateOfBirth, GETDATE())
)
GO

Als u een entiteit wilt maken om de records in de bovenstaande tabel weer te geven, moet u het kenmerk DatabaseGenerated met de waarde Computed .

[Table("Person")]
public class Person
{
    [Key, StringLength(100)]
    public string Name { get; set; }
    public DateTime DateOfBirth { get; set; }
    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public int Age { get; set; }
}

[NotMapped] -kenmerk

Volgens de Code-First-conventie maakt Entity Framework een kolom voor elke openbare eigenschap die van een ondersteund gegevenstype is en zowel een getter als een setter heeft. [NotMapped] annotatie moet worden toegepast op alle eigenschappen waarvoor we GEEN kolom in een databasetabel willen hebben.

Een voorbeeld van een eigenschap die we misschien niet in de database willen opslaan, is de volledige naam van een student op basis van zijn voor- en achternaam. Dat kan direct worden berekend en het is niet nodig om het in de database op te slaan.

public string FullName => string.Format("{0} {1}", FirstName, LastName);

De eigenschap "FullName" heeft alleen een getter en geen setter, dus standaard maakt Entity Framework er GEEN kolom voor.

Een ander voorbeeld van een eigenschap die we misschien niet in de database willen opslaan, is de "AverageGrade" van een student. We willen de AverageGrade niet on-demand krijgen; in plaats daarvan kunnen we elders een routine hebben die het berekent.

[NotMapped]
public float AverageGrade { set; get; }

De "AverageGrade" moet worden gemarkeerd als [NotMapped] annotatie, anders zal Entity Framework er een kolom voor maken.

using System.ComponentModel.DataAnnotations.Schema;

public class Student
{
    public int Id { set; get; }

    public string FirstName { set; get; }

    public string LastName { set; get; }

    public string FullName => string.Format("{0} {1}", FirstName, LastName);

    [NotMapped]
    public float AverageGrade { set; get; }
}

Voor de bovengenoemde entiteit zien we binnen DbMigration.cs

CreateTable(
    "dbo.Students",
     c => new
         {
             Id = c.Int(nullable: false, identity: true),
             FirstName = c.String(),
             LastName = c.String(),
         })
     .PrimaryKey(t => t.Id);

en in SQL Server Management Studio

voer hier de afbeeldingsbeschrijving in

[Tabel] -kenmerk

[Table("People")]
public class Person
{
    public int PersonID { get; set; }
    public string PersonName { get; set; }    
}

Vertelt Entity Framework om een specifieke tabelnaam te gebruiken in plaats van er een te genereren (bijv. Person of Persons )

We kunnen ook een schema voor de tabel opgeven met het kenmerk [Tabel]

[Table("People", Schema = "domain")]

[Kolom] attribuut

public class Person
{
    public int PersonID { get; set; }
    
    [Column("NameOfPerson")]
    public string PersonName { get; set; }    
}

Vertelt Entity Framework om een specifieke kolomnaam te gebruiken in plaats van de naam van de eigenschap. U kunt ook het gegevenstype van de database en de volgorde van de kolom in de tabel opgeven:

[Column("NameOfPerson", TypeName = "varchar", Order = 1)]
public string PersonName { get; set; }    

[Index] attribuut

public class Person
{
    public int PersonID { get; set; }
    public string PersonName { get; set; }

    [Index]
    public int Age { get; set; }
}

Maakt een database-index voor een kolom of een reeks kolommen.

[Index("IX_Person_Age")]
public int Age { get; set; }

Hiermee maakt u een index met een specifieke naam.

[Index(IsUnique = true)]
public int Age { get; set; }

Dit creëert een unieke index.

[Index("IX_Person_NameAndAge", 1)]
public int Age { get; set; }

[Index("IX_Person_NameAndAge", 2)]
public string PersonName { get; set; }

Hiermee maakt u een samengestelde index met behulp van 2 kolommen. Hiertoe moet u dezelfde indexnaam opgeven en een kolomvolgorde opgeven.

Opmerking : het kenmerk Index werd geïntroduceerd in Entity Framework 6.1. Als u een eerdere versie gebruikt, is de informatie in deze sectie niet van toepassing.

[ForeignKey (string)] -kenmerk

Hiermee geeft u de naam van de aangepaste externe sleutel op als een externe sleutel die niet voldoet aan de EF-conventie gewenst is.

public class Person 
{
    public int IdAddress { get; set; }

    [ForeignKey(nameof(IdAddress))]
    public virtual Address HomeAddress { get; set; }
}

Dit kan ook worden gebruikt wanneer u meerdere relaties met hetzelfde entiteitstype hebt.

using System.ComponentModel.DataAnnotations.Schema;

public class Customer
{
    ...

    public int MailingAddressID { get; set; }
    public int BillingAddressID { get; set; }

    [ForeignKey("MailingAddressID")]
    public virtual Address MailingAddress { get; set; }
    [ForeignKey("BillingAddressID")]
    public virtual Address BillingAddress { get; set; }
}

Zonder de ForeignKey kenmerken kan EF ze door elkaar halen en de waarde van BillingAddressID bij het ophalen van het MailingAddress , of het kan gewoon een andere naam voor de kolom Address_MailingAddress_Id op basis van zijn eigen naamgevingsconventies (zoals Address_MailingAddress_Id ) en proberen dat te gebruiken in plaats daarvan (wat zou resulteren in een fout als u dit met een bestaande database gebruikt).

[StringLength (int)] -kenmerk

using System.ComponentModel.DataAnnotations;

public class Post
{
    public int Id { get; set; }
    
    [StringLength(100)]
    public string Title { get; set;}

    [StringLength(300)]
    public string Abstract { get; set; }
    
    public string Description { get; set; }
}

Definieert een maximale lengte voor een stringveld.

voer hier de afbeeldingsbeschrijving in

Opmerking : het kan ook worden gebruikt met asp.net-mvc als validatiekenmerk.

[Tijdstempel] -kenmerk

[TimeStamp] -kenmerk kan worden toegepast op slechts één byte-array-eigenschap in een bepaalde entiteitsklasse. Entity Framework maakt een niet-nullable tijdstempelkolom in de databasetabel voor die eigenschap. Entity Framework gebruikt deze TimeStamp-kolom automatisch bij gelijktijdigheidscontrole.

using System.ComponentModel.DataAnnotations.Schema;

public class Student
{
    public int Id { set; get; }

    public string FirstName { set; get; }

    public string LastName { set; get; }    

    [Timestamp]
    public byte[] RowVersion { get; set; }
}

voer hier de afbeeldingsbeschrijving in

[ConcurrencyCheck] Attribuut

Dit kenmerk wordt toegepast op de klasse-eigenschap. U kunt het kenmerk ConcurrencyCheck gebruiken wanneer u bestaande kolommen voor gelijktijdigheidscontrole wilt gebruiken en geen afzonderlijke tijdstempelkolom voor gelijktijdigheid.

using System.ComponentModel.DataAnnotations;

public class Author
{
    public int AuthorId { get; set; }
     
    [ConcurrencyCheck]
    public string AuthorName { get; set; }
}

Uit het bovenstaande voorbeeld wordt het kenmerk ConcurrencyCheck toegepast op de eigenschap AuthorName van de klasse Author. Dus, Code-First zal de kolom AuthorName opnemen in de update-opdracht (waar clausule) om te controleren op optimistische overeenstemming.

[InverseProperty (string)] attribuut

using System.ComponentModel.DataAnnotations.Schema;

public class Department  
{  
    ...

    public virtual ICollection<Employee> PrimaryEmployees { get; set; }  
    public virtual ICollection<Employee> SecondaryEmployees { get; set; }  
}  
  
public class Employee  
{  
    ...

    [InverseProperty("PrimaryEmployees")]  
    public virtual Department PrimaryDepartment { get; set; }  
  
    [InverseProperty("SecondaryEmployees")]  
    public virtual Department SecondaryDepartment { get; set; }  
}  

InverseProperty kan worden gebruikt om tweerichtingsrelaties te identificeren wanneer er meerdere tweerichtingsrelaties bestaan tussen twee entiteiten.

Het vertelt Entity Framework welke navigatie-eigenschappen het moet matchen met eigenschappen aan de andere kant.

Entity Framework weet niet welke navigatie-eigenschappenkaart met welke eigenschappen aan de andere kant wanneer er meerdere bidirectionele relaties bestaan tussen twee entiteiten.

Het heeft de naam van de overeenkomstige navigatie-eigenschap in de gerelateerde klasse nodig als parameter.

Dit kan ook worden gebruikt voor entiteiten die een relatie hebben met andere entiteiten van hetzelfde type, waardoor een recursieve relatie wordt gevormd.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

public class TreeNode
{
    [Key]
    public int ID { get; set; }
    public int ParentID { get; set; }

    ...

    [ForeignKey("ParentID")]
    public TreeNode ParentNode { get; set; }
    [InverseProperty("ParentNode")]
    public virtual ICollection<TreeNode> ChildNodes { get; set; }
}

Let ook op het gebruik van het kenmerk ForeignKey om de kolom op te geven die wordt gebruikt voor de externe sleutel in de tabel. In het eerste voorbeeld zou bij de twee eigenschappen van de klasse Employee het kenmerk ForeignKey kunnen zijn toegepast om de kolomnamen te definiëren.

[ComplexType] -kenmerk

using System.ComponentModel.DataAnnotations.Schema;

[ComplexType] 
public class BlogDetails 
{ 
    public DateTime? DateCreated { get; set; } 
 
    [MaxLength(250)] 
    public string Description { get; set; } 
}

public class Blog
{
    ...

    public BlogDetails BlogDetail { get; set; }
}

Markeer de klasse als complex type in Entity Framework.

Complexe typen (of waardeobjecten in domeingestuurd ontwerp) kunnen niet op zichzelf worden gevolgd, maar worden wel gevolgd als onderdeel van een entiteit. Daarom heeft BlogDetails in het voorbeeld geen sleuteleigenschap.

Complex Type dat wordt gevolgd

Ze kunnen nuttig zijn bij het beschrijven van domeinentiteiten in meerdere klassen en het in lagen samenvoegen van die klassen tot een complete entiteit.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow