Comparteix a través de


Convenciones de Code First

Code First permite describir un modelo mediante clases .NET de C# o Visual Basic. La forma básica del modelo se detecta mediante convenciones. Las convenciones son conjuntos de reglas que se usan para configurar automáticamente un modelo conceptual basado en definiciones de clase al trabajar con Code First. Las convenciones se definen en el espacio de nombres System.Data.Entity.ModelConfiguration.Conventions.

Puede configurar aún más el modelo mediante anotaciones de datos o la API fluida. La prioridad se da a la configuración a través de la API fluida seguida de anotaciones de datos y, a continuación, convenciones. Para obtener más información, consulte Anotaciones de datos, Fluent API - Relationships, Fluent API - Types & Properties yFluent API con VB.NET.

Hay disponible una lista detallada de convenciones de Code First en la documentación de api. En este tema se proporciona información general sobre las convenciones usadas por Code First.

Detección de tipos

Al usar el desarrollo de Code First, normalmente comienza escribiendo clases de .NET Framework que definen el modelo conceptual (dominio). Además de definir las clases, también debe indicar a DbContext qué tipos desea incluir en el modelo. Para ello, defina una clase de contexto que derive de DbContext y exponga las propiedades dbSet para los tipos que desea formar parte del modelo. Code First incluirá estos tipos y también extraerá los tipos a los que se hace referencia, incluso si los tipos a los que se hace referencia se definen en un ensamblado diferente.

Si los tipos participan en una jerarquía de herencia, basta con definir una propiedad DbSet para la clase base y los tipos derivados se incluirán automáticamente, si están en el mismo ensamblado que la clase base.

En el ejemplo siguiente, solo hay una propiedad DbSet definida en la clase SchoolEntities (Departments). Code First usa esta propiedad para detectar y extraer los tipos a los que se hace referencia.

public class SchoolEntities : DbContext
{
    public DbSet<Department> Departments { get; set; }
}

public class Department
{
    // Primary key
    public int DepartmentID { get; set; }
    public string Name { get; set; }

    // Navigation property
    public virtual ICollection<Course> Courses { get; set; }
}

public class Course
{
    // Primary key
    public int CourseID { get; set; }

    public string Title { get; set; }
    public int Credits { get; set; }

    // Foreign key
    public int DepartmentID { get; set; }

    // Navigation properties
    public virtual Department Department { get; set; }
}

public partial class OnlineCourse : Course
{
    public string URL { get; set; }
}

public partial class OnsiteCourse : Course
{
    public string Location { get; set; }
    public string Days { get; set; }
    public System.DateTime Time { get; set; }
}

Si desea excluir un tipo del modelo, use el atributo NotMapped o la API fluent DbModelBuilder.Ignore .

modelBuilder.Ignore<Department>();

Convención de clave principal

Code First deduce que una propiedad es una clave principal si una propiedad de una clase se denomina "ID" (no distingue mayúsculas de minúsculas) o el nombre de clase seguido de "ID". Si el tipo de la propiedad de clave principal es numérico o GUID, se configurará como una columna de identidad.

public class Department
{
    // Primary key
    public int DepartmentID { get; set; }

    . . .  

}

Convención de relación

En Entity Framework, las propiedades de navegación proporcionan una manera de navegar por una relación entre dos tipos de entidad. Cada objeto puede tener una propiedad de navegación para cada relación en la que participa. Las propiedades de navegación permiten navegar y administrar relaciones en ambas direcciones, devolviendo un objeto de referencia (si la multiplicidad es uno o cero o uno) o una colección (si la multiplicidad es muchas). Code First deduce las relaciones en función de las propiedades de navegación definidas en los tipos.

Además de las propiedades de navegación, se recomienda incluir propiedades de clave externa en los tipos que representan objetos dependientes. Cualquier propiedad con el mismo tipo de datos que la propiedad principal de clave principal y con un nombre que sigue uno de los siguientes formatos representa una clave externa para la relación: "<nombre de propiedad de navegación><nombre de propiedad principal de clave principal>", "<nombre de la clase principal><nombre de propiedad de clave principal>" o "<nombre de propiedad de clave principal de la propiedad principal>". Si se encuentran varias coincidencias, la prioridad se da en el orden indicado anteriormente. La detección de claves externas no distingue mayúsculas de minúsculas. Cuando se detecta una propiedad de clave externa, Code First deduce la multiplicidad de la relación en función de la nulabilidad de la clave externa. Si la propiedad es anulable, la relación se registra como opcional; de lo contrario, la relación se registra como obligatoria.

Si una clave externa de la entidad dependiente no acepta valores NULL, Code First establece la eliminación en cascada en la relación. Si una clave externa de la entidad dependiente es nula, Code First no establece la eliminación en cascada en la relación y, cuando se elimina el principal, la clave externa se establecerá en nulo. El comportamiento de eliminación en cascada y multiplicidad detectado por convención se puede invalidar mediante la API fluida.

En el ejemplo siguiente se usan las propiedades de navegación y una clave externa para definir la relación entre las clases Department y Course.

public class Department
{
    // Primary key
    public int DepartmentID { get; set; }
    public string Name { get; set; }

    // Navigation property
    public virtual ICollection<Course> Courses { get; set; }
}

public class Course
{
    // Primary key
    public int CourseID { get; set; }

    public string Title { get; set; }
    public int Credits { get; set; }

    // Foreign key
    public int DepartmentID { get; set; }

    // Navigation properties
    public virtual Department Department { get; set; }
}

Nota:

Si tiene varias relaciones entre los mismos tipos (por ejemplo, supongamos que define las clases Person y Book , donde la clase Person contiene las propiedades de navegación ReviewedBooks y AuthoredBooks y la clase Book contiene las propiedades de navegación Author y Reviewer ) debe configurar manualmente las relaciones mediante anotaciones de datos o la API fluida. Para obtener más información, consulte Anotaciones de datos: relaciones y relaciones de Fluent API.

Convención de tipos complejos

Cuando Code First detecta una definición de clase donde no se puede deducir una clave principal y no se registra ninguna clave principal a través de anotaciones de datos o la API fluida, el tipo se registra automáticamente como un tipo complejo. La detección de tipos complejos también requiere que el tipo no tenga propiedades que hagan referencia a tipos de entidad y que una propiedad de colección en otro tipo no haga referencia a él. Dadas las siguientes definiciones de clase, Code First deduciría que Details es un tipo complejo porque no tiene ninguna clave principal.

public partial class OnsiteCourse : Course
{
    public OnsiteCourse()
    {
        Details = new Details();
    }

    public Details Details { get; set; }
}

public class Details
{
    public System.DateTime Time { get; set; }
    public string Location { get; set; }
    public string Days { get; set; }
}

Convención de cadena de conexión

Para obtener información sobre las convenciones que DbContext usa para detectar la conexión para usar, consulte Conexiones y modelos.

Quitar convenciones

Puede quitar cualquiera de las convenciones definidas en el espacio de nombres System.Data.Entity.ModelConfiguration.Conventions. En el ejemplo siguiente se quita PluralizingTableNameConvention.

public class SchoolEntities : DbContext
{
     . . .

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // Configure Code First to ignore PluralizingTableName convention
        // If you keep this convention, the generated tables  
        // will have pluralized names.
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

Convenciones personalizadas

Las convenciones personalizadas se admiten en EF6 y versiones posteriores. Para obtener más información, vea Convenciones de Custom Code First.