Ricerca…


Osservazioni

Esistono due modi generali per specificare come HOW Entity Framework mapperà le classi POCO alle tabelle, alle colonne, ecc. Del database: Annotazioni dei dati e API Fluent .

Sebbene le annotazioni dei dati siano semplici da leggere e comprendere, mancano alcune funzionalità, come la specifica del comportamento "Cascata all'eliminazione" per un'entità. L'API Fluent d'altra parte è un po 'più complessa da usare, ma offre un set di funzionalità molto più avanzato.

Modelli di mappatura

EntityFramewok Fluent API è un modo potente ed elegante per mappare i tuoi modelli di dominio code-first al database sottostante. Questo può anche essere usato con code-first con il database esistente . Sono disponibili due opzioni quando si utilizza l' API Fluent : è possibile mappare direttamente i modelli sul metodo OnModelCreating oppure è possibile creare classi di mapping che ereditano da EntityTypeConfiguration e quindi aggiungere tali modelli a modelBuilder sul metodo OnModelCreating . La seconda opzione è quella che preferisco e mostrerò un esempio.

Fase 1: creare un modello.

public class Employee
{
    public int Id { get; set; }
    public string Surname { get; set; }    
    public string FirstName { get; set; }    
    public string LastName { get; set; }        
    public short Age { get; set; }    
    public decimal MonthlySalary { get; set; }
        
    public string FullName
    {
        get
        {
            return $"{Surname} {FirstName} {LastName}";
        }
    }
}

Passo 2: crea una classe mapper

public class EmployeeMap
    : EntityTypeConfiguration<Employee>
{
    public EmployeeMap()
    {
        // Primary key
        this.HasKey(m => m.Id);
        
        this.Property(m => m.Id)
            .HasColumnType("int")
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
            
        // Properties
        this.Property(m => m.Surname)
            .HasMaxLength(50);
            
        this.Property(m => m.FirstName)
            .IsRequired()
            .HasMaxLength(50);
            
        this.Property(m => m.LastName)
            .HasMaxLength(50);
            
        this.Property(m => m.Age)
            .HasColumnType("smallint");
            
        this.Property(m => m.MonthlySalary)
            .HasColumnType("number")
            .HasPrecision(14, 5);
            
        this.Ignore(m => m.FullName);
        
        // Table & column mappings
        this.ToTable("TABLE_NAME", "SCHEMA_NAME");
        this.Property(m => m.Id).HasColumnName("ID");
        this.Property(m => m.Surname).HasColumnName("SURNAME");
        this.Property(m => m.FirstName).HasColumnName("FIRST_NAME");
        this.Property(m => m.LastName).HasColumnName("LAST_NAME");
        this.Property(m => m.Age).HasColumnName("AGE");
        this.Property(m => m.MonthlySalary).HasColumnName("MONTHLY_SALARY");
    }
}

Cerchiamo di spiegare i mapping:

  • HasKey : definisce la chiave primaria. È anche possibile utilizzare chiavi primarie composte . Ad esempio: this.HasKey (m => new {m.DepartmentId, m.PositionId}) .
  • Proprietà : ci consente di configurare le proprietà del modello.
  • HasColumnType : specifica il tipo di colonna del livello del database. Si noti che, può essere diverso per diversi database come Oracle e MS SQL.
  • HasDatabaseGeneratedOption - specifica se la proprietà è calcolata a livello di database. I PK numerici sono DatabaseGeneratedOption.Identity per impostazione predefinita, è necessario specificare DatabaseGeneratedOption.None se non si desidera che siano tali.
  • HasMaxLength : limita la lunghezza della stringa.
  • IsRequired : contrassegna la proprietà come requiered.
  • HasPrecision : ci consente di specificare la precisione per i decimali.
  • Ignora : ignora completamente la proprietà e non la associa al database. Abbiamo ignorato FullName, perché non vogliamo questa colonna al nostro tavolo.
  • ToTable : specifica il nome della tabella e il nome dello schema (facoltativo) per il modello.
  • HasColumnName : associa la proprietà al nome della colonna. Questo non è necessario quando i nomi delle proprietà e i nomi delle colonne sono identici.

Passaggio 3: aggiunta della classe di mapping alle configurazioni.

Dobbiamo dire a EntityFramework di usare la nostra classe mapper. Per fare ciò, dobbiamo aggiungerlo a modelBuilder.Configurations sul metodo OnModelCreating :

public class DbContext()
    : base("Name=DbContext")
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new EmployeeMap());
    }
}

E questo è tutto. Siamo pronti per partire.

Chiave primaria

Utilizzando il metodo .HasKey (), una proprietà può essere configurata esplicitamente come chiave primaria dell'entità.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ..

        modelBuilder.Entity<Person>().HasKey(p => p.PersonKey);
    }
}

Chiave primaria composita

Utilizzando il metodo .HasKey (), un insieme di proprietà può essere configurato esplicitamente come chiave primaria composita dell'entità.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ..

        modelBuilder.Entity<Person>().HasKey(p => new { p.FirstName, p.LastName });
    }
}

Lunghezza massima

Utilizzando il metodo .HasMaxLength (), il numero massimo di caratteri può essere configurato per una proprietà.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ..

        modelBuilder.Entity<Person>()
                    .Property(t => t.Name)
                    .HasMaxLength(100);
    }
}

La colonna risultante con la lunghezza della colonna specificata:

inserisci la descrizione dell'immagine qui

Proprietà richieste (NOT NULL)

Usando il metodo .IsRequired (), le proprietà possono essere specificate come obbligatorie, il che significa che la colonna avrà un vincolo NOT NULL.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // ..

        modelBuilder.Entity<Person>()
                    .Property(t => t.Name)
                    .IsRequired();
    }
}

La colonna risultante con il vincolo NOT NULL:

inserisci la descrizione dell'immagine qui

Esplicita denominazione di chiave esterna

Quando esiste una proprietà di navigazione su un modello, Entity Framework creerà automaticamente una colonna Chiave esterna. Se un determinato nome di chiave esterna è desiderato ma non è contenuto come una proprietà nel modello, può essere impostato in modo esplicito utilizzando l'API Fluent. Utilizzando il metodo Map mentre si stabilisce la relazione Foreign Key, è possibile utilizzare qualsiasi nome univoco per le chiavi esterne.

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

public class Employee
{
    property int Id { get; set; }
    property Company Employer { get; set; }
}

public class EmployeeContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Employee>()
                    .HasRequired(x => x.Employer)
                    .WithRequiredDependent()
                    .Map(m => m.MapKey("EmployerId"));
    }
}

Dopo aver specificato la relazione, il metodo Map consente di impostare esplicitamente il nome della chiave MapKey eseguendo MapKey . In questo esempio, ciò che sarebbe risultato in un nome di colonna di Employer_Id è ora EmployerId.



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow