Resumen

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#:

public class User
{
    public int ID { get; set; }
    public string Name { get; set; } = ""; // valor por defecto para evitar null warnings
    public string Email { get; set; } = ""; // valor por defecto
    // Propiedad de navegación para las tareas asignadas al usuario
    public ICollection<TaskItem> Tasks { get; set; } = new List<TaskItem>();
}

public class TaskItem
{
    public int ID { get; set; }
    public string Title { get; set; } = ""; // valor por defecto
    public bool IsCompleted { get; set; }
    public int UserID { get; set; } // clave foránea hacia User
    public User? 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.
public class AppDbContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<TaskItem> Task { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        // User
        modelBuilder.Entity<User>(entity =>
        {
            entity.ToTable("users");
            entity.HasKey(u => u.ID);
            entity.Property(u => u.Name)
                  .IsRequired()
                  .HasMaxLength(100);
            entity.Property(u => u.Email)
                  .IsRequired()
                  .HasMaxLength(200);
        });

        // TaskItem
        modelBuilder.Entity<TaskItem>(entity =>
        {
            entity.ToTable("task");
            entity.HasKey(t => t.ID);
            entity.Property(t => t.IsCompleted)
                  .HasDefaultValue(false); // por defecto, no completada

            entity.HasOne(t => t.User)
                  .WithMany(u => u.Tasks)
                  .HasForeignKey(t => t.UserID);
        });
    }
}

¿Qué ventajas aporta Fluent API en este contexto?

  • 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.