簡體   English   中英

如何修復從 EF Core 3 遷移到 EF Core 6 導致循環中斷的查詢

[英]How To Fix Query With Cycles Broken By Migration from EF Core 3 To EF Core 6

從 EF Core 3 遷移到 EF Core 6 后,此查詢:

private async Task<Variation[]> GetPizzasInOrder(Uuid[] productsInOrder, CancellationToken ct)
{
    return await _clientCheckupsGatewayContext.MetaProducts
        .SelectMany(mp => mp.Variations)
        .Where(v => productsInOrder.Contains(v.Id))
        .Include(v => v.MetaProduct)
        .ToArrayAsync(ct);
}

開始拋出錯誤:

System.InvalidOperationException:跟蹤查詢正在嘗試在其結果中投影沒有相應所有者的自有實體,但如果沒有其所有者,則無法跟蹤自有實體。 要么在結果中包含所有者實體,要么使用“AsNoTracking”使查詢不跟蹤。

更改為“AsNoTracking()”會產生另一個錯誤:

private async Task<Variation[]> GetPizzasInOrder(Uuid[] productsInOrder, CancellationToken ct)
{
    return await _clientCheckupsGatewayContext.MetaProducts
        .AsNoTracking()
        .SelectMany(mp => mp.Variations)
        .Where(v => productsInOrder.Contains(v.Id))
        .Include(v => v.MetaProduct)
        .ToArrayAsync(ct);
}

System.InvalidOperationException:包含路徑“MetaProduct->Variations”導致循環。 無跟蹤查詢中不允許循環; 使用跟蹤查詢或刪除循環。

public class MetaProduct
{
    public Uuid Id { get; }
    public IReadOnlyList<Variation> Variations => _variations.ToArray();
    private List<Variation> _variations = null!;
}

public class Variation
{
    public Uuid Id { get; }

    public MetaProduct? MetaProduct { get; }
}

關系配置:

private static void MapMetaProducts(ModelBuilder modelBuilder)
{
    var tagsConverter = new ValueConverter<string[], string>(
        v => JsonConvert.SerializeObject(v),
        v => JsonConvert.DeserializeObject<string[]>(v)
    );

    var builder = modelBuilder.Entity<MetaProduct>().ToTable("metaproducts");
    builder.HasKey(p => p.Id);

    builder.Property(p => p.Id).HasColumnName("Id");

    builder.OwnsMany(mp => mp.Variations,
        vBuilder =>
        {
            vBuilder.ToTable("metaproducts_variations");

            vBuilder.WithOwner(v => v.MetaProduct!);

            vBuilder.Property(v => v.Id).HasColumnName("Id");

            vBuilder.HasKey("Id");
        });
}

如何解決?

在我看來,您要做的只是返回一個 Variations 數組,其中 Variation Id 在列表中。

此外,您的變體在擁有時不應具有返回 MetaProduct 的導航屬性。 它實際上應該只在其所有者的上下文中檢索。

如果您真的想從 Variation 導航到 MetaProduct,那么您應該重新考慮 Variation 是否真的是一個“擁有”實體或只是一個相關實體。

問題是您正在從 MetaProducts 輸入查詢,但隨后嘗試再次包含它。 如果您可以取消從 Variation 到 MetaProduct 的導航,那么以下操作將起作用:

return await _clientCheckupsGatewayContext.MetaProducts
    .AsNoTracking()
    .SelectMany(mp => mp.Variations)
    .Where(v => productsInOrder.Contains(v.Id))
    .ToArrayAsync(ct);

如果您真的想以另一種方式導航,那么您需要將 Variation 提升為相關實體(HasMany 而不是 OwnsMany),然后在您的上下文中將 Variations 公開為 DbSet。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM