// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Linq; using System.Reflection; using System.Threading.Tasks; using EntityFrameworkCore.Jet.FunctionalTests.TestUtilities; using EntityFrameworkCore.Jet.Infrastructure; using EntityFrameworkCore.Jet.Infrastructure.Internal; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.TestUtilities; using Xunit; namespace EntityFrameworkCore.Jet.FunctionalTests.Query; #nullable disable public class AdHocQuerySplittingQueryJetTest(NonSharedFixture fixture) : AdHocQuerySplittingQueryTestBase(fixture) { protected override ITestStoreFactory TestStoreFactory => JetTestStoreFactory.Instance; private static readonly FieldInfo _querySplittingBehaviorFieldInfo = typeof(RelationalOptionsExtension).GetField("_querySplittingBehavior", BindingFlags.NonPublic | BindingFlags.Instance); protected override DbContextOptionsBuilder SetQuerySplittingBehavior( DbContextOptionsBuilder optionsBuilder, QuerySplittingBehavior splittingBehavior) { new JetDbContextOptionsBuilder(optionsBuilder).UseQuerySplittingBehavior(splittingBehavior); return optionsBuilder; } protected override DbContextOptionsBuilder ClearQuerySplittingBehavior(DbContextOptionsBuilder optionsBuilder) { var extension = optionsBuilder.Options.FindExtension(); if (extension == null) { extension = new JetOptionsExtension(); } else { _querySplittingBehaviorFieldInfo.SetValue(extension, null); } ((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension); return optionsBuilder; } protected override TestStore CreateTestStore25225() { var testStore = JetTestStore.Create(StoreName); testStore.UseConnectionString = true; return testStore; } public override async Task Can_configure_SingleQuery_at_context_level() { await base.Can_configure_SingleQuery_at_context_level(); AssertSql( """ SELECT `p`.`Id`, `c`.`Id`, `c`.`ParentId` FROM `Parents` AS `p` LEFT JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` """, // """ SELECT `c`.`Id`, `c`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT `p`.`Id`, `c`.`Id`, `c`.`ParentId`, `a`.`Id`, `a`.`ParentId` FROM (`Parents` AS `p` LEFT JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId`) LEFT JOIN `AnotherChild` AS `a` ON `p`.`Id` = `a`.`ParentId` ORDER BY `p`.`Id`, `c`.`Id` """); } public override async Task Can_configure_SplitQuery_at_context_level() { await base.Can_configure_SplitQuery_at_context_level(); AssertSql( """ SELECT `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` """, // """ SELECT `c`.`Id`, `c`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT `p`.`Id`, `c`.`Id`, `c`.`ParentId` FROM `Parents` AS `p` LEFT JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` """, // """ SELECT `c`.`Id`, `c`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT `a`.`Id`, `a`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `AnotherChild` AS `a` ON `p`.`Id` = `a`.`ParentId` ORDER BY `p`.`Id` """); } public override async Task Unconfigured_query_splitting_behavior_throws_a_warning() { await base.Unconfigured_query_splitting_behavior_throws_a_warning(); AssertSql( """ SELECT `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` """, // """ SELECT `c`.`Id`, `c`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT `a`.`Id`, `a`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `AnotherChild` AS `a` ON `p`.`Id` = `a`.`ParentId` ORDER BY `p`.`Id` """); } public override async Task Using_AsSingleQuery_without_context_configuration_does_not_throw_warning() { await base.Using_AsSingleQuery_without_context_configuration_does_not_throw_warning(); AssertSql( """ SELECT `p`.`Id`, `c`.`Id`, `c`.`ParentId`, `a`.`Id`, `a`.`ParentId` FROM (`Parents` AS `p` LEFT JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId`) LEFT JOIN `AnotherChild` AS `a` ON `p`.`Id` = `a`.`ParentId` ORDER BY `p`.`Id`, `c`.`Id` """); } public override async Task SplitQuery_disposes_inner_data_readers() { await base.SplitQuery_disposes_inner_data_readers(); AssertSql( """ SELECT `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` """, // """ SELECT `c`.`Id`, `c`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT `a`.`Id`, `a`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `AnotherChild` AS `a` ON `p`.`Id` = `a`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` """, // """ SELECT `c`.`Id`, `c`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT `a`.`Id`, `a`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `AnotherChild` AS `a` ON `p`.`Id` = `a`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT TOP 2 `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` """, // """ SELECT `c`.`Id`, `c`.`ParentId`, `p0`.`Id` FROM ( SELECT TOP 1 `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` ) AS `p0` INNER JOIN `Child` AS `c` ON `p0`.`Id` = `c`.`ParentId` ORDER BY `p0`.`Id` """, // """ SELECT `a`.`Id`, `a`.`ParentId`, `p1`.`Id` FROM ( SELECT TOP 1 `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` ) AS `p1` INNER JOIN `AnotherChild` AS `a` ON `p1`.`Id` = `a`.`ParentId` ORDER BY `p1`.`Id` """, // """ SELECT TOP 2 `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` """, // """ SELECT `c`.`Id`, `c`.`ParentId`, `p0`.`Id` FROM ( SELECT TOP 1 `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` ) AS `p0` INNER JOIN `Child` AS `c` ON `p0`.`Id` = `c`.`ParentId` ORDER BY `p0`.`Id` """, // """ SELECT `a`.`Id`, `a`.`ParentId`, `p1`.`Id` FROM ( SELECT TOP 1 `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` ) AS `p1` INNER JOIN `AnotherChild` AS `a` ON `p1`.`Id` = `a`.`ParentId` ORDER BY `p1`.`Id` """); } [ConditionalFact] public virtual async Task Using_AsSplitQuery_without_multiple_active_result_sets_works() { var contextFactory = await InitializeAsync( seed: c => c.SeedAsync(), createTestStore: () => JetTestStore.Create(StoreName)); using var context = contextFactory.CreateContext(); context.Parents.Include(p => p.Children1).Include(p => p.Children2).AsSplitQuery().ToList(); AssertSql( """ SELECT `p`.`Id` FROM `Parents` AS `p` ORDER BY `p`.`Id` """, // """ SELECT `c`.`Id`, `c`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `Child` AS `c` ON `p`.`Id` = `c`.`ParentId` ORDER BY `p`.`Id` """, // """ SELECT `a`.`Id`, `a`.`ParentId`, `p`.`Id` FROM `Parents` AS `p` INNER JOIN `AnotherChild` AS `a` ON `p`.`Id` = `a`.`ParentId` ORDER BY `p`.`Id` """); } public override async Task NoTracking_split_query_creates_only_required_instances(bool async) { await base.NoTracking_split_query_creates_only_required_instances(async); AssertSql( """ SELECT TOP 1 `t`.`Id`, `t`.`Value` FROM `Tests` AS `t` ORDER BY `t`.`Id` """); } }