【问题标题】:LINQ Add/AddRange are overriding last rowLINQ Add/AddRange 覆盖最后一行
【发布时间】:2022-01-19 12:48:55
【问题描述】:

我正在尝试使用 'Add' 或 'AddRange' 方法将列表添加到表中,但它们继续覆盖最后一行,最后我在数据库中只有一行。

查询服务代码:

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();
        }

    }

如您所见,我一直在尝试不同的事情。我一直在阅读将对象初始化程序放入循环中的解决方案的帖子,但我从一开始就这样做了。如果我在循环中调试并停止,我已检查插入第一行是否正常(使用“添加”方法),但随后用下一行覆盖它。

我敢打赌这是一件愚蠢的事情,因为我仍在学习 EF Core,但我找不到错误。

更新

ProductTag 类:

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; }
}

数据库表配置:

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); 
    }

【问题讨论】:

  • LINQ 没有 Add/AddRange 顺便说一句。标题可能更适合“EF Core...”
  • ProductTag的主键是什么?
  • 建立关系不需要同时设置XId和X
  • 调用SaveChanges时,执行的是什么SQL? (在启动时将.LogTo(System.Console.WriteLine, Microsoft.Extensions.Logging.LogLevel.Information) 放到您的 UseSqlServer 调用中)

标签: c# database linq entity-framework-core dbcontext


【解决方案1】:

问题是数据库设置中的错误配置:

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
}

当我看到数据库配置时,我意识到它出了什么问题。我将其设置为 1..1 关系,这是因为同一行正在更新。问题解决了,谢谢大家。

【讨论】:

  • 将您的答案从问题中移到您的答案中;避免在问题中回答问题。登陆这里的未来访问者将在答案中寻找答案。它会改进答案以显示 new 配置是什么。我认为 WithMany 而不是 WithOne
【解决方案2】:

假设 ProductTag 的 PK 等于 ProductId,您将通过 foreach 进程更新相同的产品更改标签。如果需要复制不同标签的产品,每次都需要生成新的ProductId。否则,您需要对所有标签求和,最后将 ProductTag 添加到集合中

【讨论】:

  • 别猜了;使用 cmets 确保..
猜你喜欢
  • 1970-01-01
  • 2012-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-01
  • 1970-01-01
  • 2013-10-03
  • 2014-09-06
相关资源
最近更新 更多