Search code examples
c#asp.net-coreentity-framework-coreasp.net-core-6.0ef-core-6.0

Error not having a primary key in my EF Core Entity when I try to post it even though the DbContext is not tracking changes


I have an ASP.NET Core 6 web api project with this entity in my context

public class ActividadSE
{
    public decimal Duracion { get; set; }
    public DateTime Fecha { get; set; }

    public string ProyectoId { get; set; }
    public string FaseId { get; set; }

    public string Descripcion { get; set; }

    public int UsuarioId { get; set; }
}

My context

public class SAPContextSR: DbContext
{
  public DbSet<ActividadSE> ActividadesSE { get; set; }

  public SAPContextSR(){}

  public SAPContextSR(DbContextOptions<SAPContextSR> options)
        :base(options){}

  protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder
            .UseSqlServer("Data Source=....")
            .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
            .LogTo(Console.WriteLine,
                new[] { DbLoggerCategory.Database.Command.Name },
                LogLevel.Information)
            .EnableSensitiveDataLogging();
        }

    }

 protected override void OnModelCreating(ModelBuilder modelBuilder)
 {
   modelBuilder.Entity<ActividadSE>().HasNoKey();
 }

As the api will be consumed by an angular SPA I have set up a disconnected environment with the entire DbContext as a no-tracking context

I have this action in my controller

[HttpPost]
public async Task<ActionResult<ActividadSEDTO>> PostActividad([FromBody] ActividadSEDTO actividad)
    {
        var actividadInsertada = await _actividadRepository.InsertarActividad(actividad);

        if (actividadInsertada>0)
        {
            return Ok();
        }
        else
        {
            return BadRequest();
        }
    }

And this in my repo

public async Task<int> InsertarActividad(ActividadSEDTO actividadDTO)
{
        var actividad = ActividadFromDTO(actividadDTO);
        _context.ActividadesSE.Add(actividad);
        return await _context.SaveChangesAsync();

}

private static ActividadSE ActividadFromDTO(ActividadSEDTO actividadDTO)
    {
        return new ActividadSE
        {
            ProyectoId=actividadDTO.ProyectoId,
            FaseId=actividadDTO.FaseId,
            UsuarioId=actividadDTO.UsuarioId,
            Descripcion=actividadDTO.Descripcion,
            Fecha=actividadDTO.Fecha,
            Duracion=actividadDTO.Duracion
        };
    }

But when I try to post an Actividad I get this error

System.InvalidOperationException: Unable to track an instance of type 'ActividadSE' because it does not have a primary key. Only entity types with a primary key may be tracked.

enter image description here

Any idea, please?

Thanks


Solution

  • EF uses tracking to perform CUD operations, ActividadSE is a keyless entity and as per docs:

    Are never tracked for changes in the DbContext and therefore are never inserted, updated or deleted on the database.

    You need either change table schema and provide a key for the entity (can be synthetic one) or insert the entry "manually" (via raw SQL or possibly using some other ORM/tool).