Buscar..


Observaciones

Hay dos formas generales de especificar CÓMO Entity Framework asignará las clases de POCO a las tablas, columnas, bases de datos, etc .: Anotaciones de datos y API de Fluent .

Si bien las Anotaciones de datos son fáciles de leer y comprender, carecen de ciertas características, como la especificación del comportamiento "Cascada en eliminar" para una entidad. La API Fluent, por otro lado, es un poco más compleja de usar, pero proporciona un conjunto de características mucho más avanzadas.

Modelos de mapeo

EntityFramewok Fluent API es una forma potente y elegante de mapear los modelos de su dominio primero en código a la base de datos subyacente. Esto también se puede usar con el código primero con la base de datos existente . Tiene dos opciones al usar Fluent API : puede asignar directamente sus modelos en el método OnModelCreating o puede crear clases de asignadores que heredan de EntityTypeConfiguration y luego agregar esos modelos a modelBuilder en el método OnModelCreating . La segunda opción es la que yo prefiero y voy a mostrar un ejemplo de ello.

Paso uno: Crear modelo.

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}";
        }
    }
}

Paso dos: Crear una clase de asignador

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");
    }
}

Vamos a explicar las asignaciones:

  • HasKey - define la clave principal. También se pueden utilizar claves primarias compuestas . Por ejemplo: this.HasKey (m => new {m.DepartmentId, m.PositionId}) .
  • Propiedad - nos permite configurar las propiedades del modelo.
  • HasColumnType : especifique el tipo de columna de nivel de base de datos. Tenga en cuenta que puede ser diferente para diferentes bases de datos como Oracle y MS SQL.
  • HasDatabaseGeneratedOption : especifica si la propiedad se calcula a nivel de base de datos. Las PK numéricas son DatabaseGeneratedOption.Identity de forma predeterminada, debe especificar DatabaseGeneratedOption.None si no desea que lo sean.
  • HasMaxLength - limita la longitud de la cadena.
  • IsRequired : marca la propiedad como requerida.
  • HasPrecision - nos permite especificar la precisión para decimales.
  • Ignorar : ignora la propiedad completamente y no la asigna a la base de datos. Ignoramos FullName, porque no queremos que esta columna esté en nuestra tabla.
  • ToTable : especifique el nombre de la tabla y el nombre del esquema (opcional) para el modelo.
  • HasColumnName - relaciona propiedad con nombre de columna. Esto no es necesario cuando los nombres de propiedades y los nombres de columnas son idénticos.

Paso tres: Agregar clase de mapeo a las configuraciones.

Necesitamos decirle a EntityFramework que use nuestra clase de asignador. Para hacerlo, debemos agregarlo a modelBuilder.Configurations en el método OnModelCreating :

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

Y eso es todo. Estamos listos para irnos.

Clave primaria

Al usar el método .HasKey (), una propiedad puede configurarse explícitamente como clave principal de la entidad.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

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

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

Clave primaria compuesta

Al usar el método .HasKey (), un conjunto de propiedades puede configurarse explícitamente como la clave primaria compuesta de la entidad.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

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

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

Longitud maxima

Al usar el método .HasMaxLength (), el conteo máximo de caracteres se puede configurar para una propiedad.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

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

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

La columna resultante con la longitud de columna especificada:

introduzca la descripción de la imagen aquí

Propiedades requeridas (NO NULL)

Al usar el método .IsRequired (), las propiedades se pueden especificar como obligatorias, lo que significa que la columna tendrá una restricción NO NULA.

using System.Data.Entity;    
// ..

public class PersonContext : DbContext
{
    // ..

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

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

La columna resultante con la restricción NOT NULL:

introduzca la descripción de la imagen aquí

Nombramiento de clave externa explícita

Cuando existe una propiedad de navegación en un modelo, Entity Framework creará automáticamente una columna de clave externa. Si se desea un nombre de clave externa específico, pero no está contenido como una propiedad en el modelo, se puede establecer explícitamente mediante la API Fluent. Al utilizar el método de Map mientras se establece la relación de clave externa, se puede usar cualquier nombre único para claves externas.

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"));
    }
}

Después de especificar la relación, el método Map permite que el nombre de la clave externa se establezca explícitamente ejecutando MapKey . En este ejemplo, lo que habría resultado en un nombre de columna de Employer_Id ahora es EmployerId.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow