Aprende a definir modelos C# que se convierten en tablas con Entity Framework y su Fluent API, creando una relación clara entre usuarios y tareas para una API. Verás cómo evitar avisos de nulos, configurar restricciones como longitud y requeridos, y declarar claves y relaciones para consultar datos de forma eficiente.
¿Cómo crear los modelos y propiedades base?
Comienza creando la carpeta models y dos clases: User.cs y TaskItem. La meta es crear tareas y asignar un usuario a cada una.
¿Qué carpeta y archivos se crean?
Carpeta: models.
Archivo: User.cs para el usuario.
Archivo: TaskItem para la tarea.
¿Qué propiedades definen User y TaskItem?
En User: ID (int), name (string) con valor por defecto, email (string) con valor por defecto. Se recomienda agregar datos como dirección o teléfono si aporta al dominio.
En TaskItem: ID, title (string) con valor por defecto, isCompleted (bool), userID (int) como clave foránea y la navegación user (permitiendo nulos) para obtener los datos del usuario asignado.
Ejemplo base en C#:
publicclassUser{publicint ID {get;set;}publicstring Name {get;set;}="";// valor por defecto para evitar null warningspublicstring Email {get;set;}="";// valor por defecto// Propiedad de navegación para las tareas asignadas al usuariopublicICollection<TaskItem> Tasks {get;set;}=newList<TaskItem>();}publicclassTaskItem{publicint ID {get;set;}publicstring Title {get;set;}="";// valor por defectopublicbool IsCompleted {get;set;}publicint UserID {get;set;}// clave foránea hacia UserpublicUser? User {get;set;}// navegación opcional}
¿Cómo configurar Entity Framework con Fluent API?
En AppDbContext agrega los DbSet y sobrescribe OnModelCreating para controlar nombres de tabla, claves, requeridos, longitudes y valores por defecto. Esta configuración en Fluent API hace explícita la estructura que tendrá la base de datos.
¿Cómo exponer las colecciones con DbSet?
Agrega DbSet<User> como users (plural) y DbSet<TaskItem> como task (simplificado). Cada DbSet se convierte en una tabla.
Define ToTable para nombres consistentes de tablas.
Establece HasKey para la clave primaria.
Marca propiedades IsRequired y HasMaxLength para control de datos.
Fija HasDefaultValue para comportamientos iniciales seguros.
Hace explícitas las relaciones y claves foráneas.
¿Qué relación usuario-tarea se implementa y cómo navegar?
La relación es uno a muchos: un usuario puede tener muchas tareas. En TaskItem se declara UserID como clave foránea y la navegación User. En User, una colección ICollection<TaskItem> permite acceder a las tareas asignadas.
¿Por qué usar propiedades de navegación?
Para consultar una tarea junto con su usuario en una sola operación.
Para recorrer desde el usuario a sus tareas sin escribir joins manuales.
Para inicializar la colección y evitar nulos en listas al instanciar entidades.
Acciones clave que quedaron claras:
Crear modelos y establecer valores por defecto para evitar nulos.
Configurar con Fluent API nombres de tablas, claves y restricciones.
Definir HasOne/WithMany y ForeignKey para la integridad referencial.
Inicializar la lista de tareas del usuario para evitar errores al acceder.
Reto práctico: agrega al modelo de User la propiedad role y configura su longitud y requerido con Fluent API. ¿Qué reglas pondrías y por qué?
¿Tienes dudas o quieres compartir tu avance? Comenta qué restricciones añadirías a name, email o role y cómo validarías isCompleted y title en tu escenario.
¿Hay manera de organizar un poco mejor las configuraciones de FluentAPI?
Lo pregunto porque para el ejemplo ya se venia un codigo algo grande con entidades realmente pequeñas. Para una base de datos con mayor número de entidades me parece que se volvería poco mantenible.
Si es posible, se puede crear metodos de extension para ir agregando la configuracion de acuerdo al dominio, aqui un ejemplo: