Home > front end >  LINQ Add/AddRange are overriding last row
LINQ Add/AddRange are overriding last row

Time:01-19

I'm trying to add a list to a table with the 'Add' or 'AddRange' method, but they continue overriding the last row and finally I only have one row in database.

QueryService code:

private async Task AddProductTags(Product product, List<Process> processes)
    {
        foreach(var process in processes)
        {
            var tags = await _context.Tag.Where(tag => tag.ProcessId == process.ProcessId).ToListAsync();
            List<ProductTag> productTags = new List<ProductTag>();

            foreach(var tag in tags)
            {
                //ProductTag productTag = new ProductTag();
                //productTag.ProductId = product.ProductId;
                //productTag.Product = product;
                //productTag.TagId = tag.TagId;
                //productTag.Tag = tag;
                //productTag.Value = "0";

                //productTags.Add(productTag);

                _context.ProductTag.Add(new ProductTag()
                {
                    ProductId = product.ProductId,
                    Product = product,
                    TagId = tag.TagId,
                    Tag = tag,
                    Value = "0"
                });
                await _context.SaveChangesAsync();
            };

            //_context.ProductTag.AddRange(productTags);
            //await _context.SaveChangesAsync();
        }

    }

As you can see, I've been trying different things. I've been reading posts which solution it was put the object initializer inside loop, but I did that from the beginning. If I debug and stop in the loop, I have checked that insert the first row okay (with 'Add' method), but then, override it with the next one.

I bet it is a dumb thing because I'm still learning EF Core, but I can't find the error.

UPDATED

ProductTag class:

public class ProductTag
{
    public int ProductId { get; set; }
    public int TagId { get; set; }

    public virtual Tag Tag { get; set; }

    public virtual Product Product { get; set; }

    public string Value { get; set; }
}

Database table configuration:

public ProductTagConfiguration(EntityTypeBuilder<ProductTag> entityTypeBuilder)
    {
        entityTypeBuilder.HasKey(pt => new { pt.ProductId, pt.TagId });
        entityTypeBuilder.Property(pt => pt.Value).IsRequired();

        entityTypeBuilder
            .HasOne(pt => pt.Product)
            .WithOne(p => p.ProductTag); 

        entityTypeBuilder
            .HasOne(pt => pt.Tag)
            .WithOne(t => t.ProductTag); 
    }

CodePudding user response:

The problem it was a bad configuration in the database set up:

public ProductTagConfiguration(EntityTypeBuilder<ProductTag> entityTypeBuilder)
{
    entityTypeBuilder.HasKey(pt => new { pt.ProductId, pt.TagId });
    entityTypeBuilder.Property(pt => pt.Value).IsRequired();

    entityTypeBuilder
        .HasOne(pt => pt.Product)
        .WithOne(p => p.ProductTag); // HERE IT'S THE MISTAKE

    entityTypeBuilder
        .HasOne(pt => pt.Tag)
        .WithOne(t => t.ProductTag); // AND HERE TOO
}

When I saw the database configuration, I realized what it was wrong. I was setting it to 1..1 relationship and it was because of that the same row was updating. Problem solved, thanks to all.

CodePudding user response:

Supposing ProductTag has PK equal ProductId, you're updatating the same product changing tags by foreach process. If you need to duplicate the product with different tag, you need to generate new ProductId each time. Otherwise you need to sum all the tag and, in the end, add the ProductTag to collection

  •  Tags:  
  • Related