From 6f76e55132898f2940729bba2e12f8060f1af7b4 Mon Sep 17 00:00:00 2001 From: Smit Patel Date: Tue, 19 May 2020 15:04:20 -0700 Subject: [PATCH] Test: Use AssertQuery in NorthwindIncludeQueryTestBase - Remove string based includes from base class. (will move to a different class) - Remove tests related to no tracking from base class. (will move to a different class) - Run tests for both sync/async --- .../NorthwindIncludeAsyncQueryInMemoryTest.cs | 13 - .../NorthwindIncludeQueryInMemoryTest.cs | 5 +- .../NorthwindIncludeAsyncQueryTestBase.cs | 1002 ---- .../Query/NorthwindIncludeQueryTestBase.cs | 4404 ++++------------- ...NorthwindIncludeAsyncQuerySqlServerTest.cs | 61 - .../NorthwindIncludeQuerySqlServerTest.cs | 377 +- .../NorthwindIncludeAsyncQuerySqliteTest.cs | 13 - .../Query/NorthwindIncludeQuerySqliteTest.cs | 16 +- 8 files changed, 1204 insertions(+), 4687 deletions(-) delete mode 100644 test/EFCore.InMemory.FunctionalTests/Query/NorthwindIncludeAsyncQueryInMemoryTest.cs delete mode 100644 test/EFCore.Specification.Tests/Query/NorthwindIncludeAsyncQueryTestBase.cs delete mode 100644 test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeAsyncQuerySqlServerTest.cs delete mode 100644 test/EFCore.Sqlite.FunctionalTests/Query/NorthwindIncludeAsyncQuerySqliteTest.cs diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindIncludeAsyncQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindIncludeAsyncQueryInMemoryTest.cs deleted file mode 100644 index 113cf5a9b89..00000000000 --- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindIncludeAsyncQueryInMemoryTest.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.EntityFrameworkCore.Query -{ - public class NorthwindIncludeAsyncQueryInMemoryTest : NorthwindIncludeAsyncQueryTestBase - { - public NorthwindIncludeAsyncQueryInMemoryTest(IncludeInMemoryFixture fixture) - : base(fixture) - { - } - } -} diff --git a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindIncludeQueryInMemoryTest.cs b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindIncludeQueryInMemoryTest.cs index c207cc9aa33..7022f4a9c0e 100644 --- a/test/EFCore.InMemory.FunctionalTests/Query/NorthwindIncludeQueryInMemoryTest.cs +++ b/test/EFCore.InMemory.FunctionalTests/Query/NorthwindIncludeQueryInMemoryTest.cs @@ -1,6 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +using System.Threading.Tasks; using Xunit; using Xunit.Abstractions; @@ -15,9 +16,9 @@ public NorthwindIncludeQueryInMemoryTest(IncludeInMemoryFixture fixture, ITestOu } [ConditionalTheory(Skip = "Issue#17386")] - public override void Include_collection_with_last_no_orderby(bool useString) + public override Task Include_collection_with_last_no_orderby(bool async) { - base.Include_collection_with_last_no_orderby(useString); + return base.Include_collection_with_last_no_orderby(async); } } } diff --git a/test/EFCore.Specification.Tests/Query/NorthwindIncludeAsyncQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindIncludeAsyncQueryTestBase.cs deleted file mode 100644 index 12fde7e2aa4..00000000000 --- a/test/EFCore.Specification.Tests/Query/NorthwindIncludeAsyncQueryTestBase.cs +++ /dev/null @@ -1,1002 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore.Diagnostics; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.TestModels.Northwind; -using Microsoft.EntityFrameworkCore.TestUtilities; -using Xunit; - -// ReSharper disable InconsistentNaming -// ReSharper disable AccessToDisposedClosure -namespace Microsoft.EntityFrameworkCore.Query -{ - public abstract class NorthwindIncludeAsyncQueryTestBase : IClassFixture - where TFixture : NorthwindQueryFixtureBase, new() - { - protected NorthwindIncludeAsyncQueryTestBase(TFixture fixture) => Fixture = fixture; - - protected TFixture Fixture { get; } - - [ConditionalFact] - public virtual async Task Include_collection() - { - using var context = CreateContext(); - var customers - = await context.Set() - .Include(c => c.Orders) - .ToListAsync(); - - Assert.Equal(91, customers.Count); - Assert.Equal(830, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(91 + 830, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_order_by_subquery() - { - using var context = CreateContext(); - var customer - = await context.Set() - .Include(c => c.Orders) - .Where(c => c.CustomerID == "ALFKI") - .OrderBy(c => c.Orders.OrderBy(o => o.EmployeeID).Select(o => o.OrderDate).FirstOrDefault()) - .FirstOrDefaultAsync(); - - Assert.NotNull(customer); - Assert.NotNull(customer.Orders); - Assert.Equal(6, customer.Orders.Count); - } - - [ConditionalFact] - public virtual async Task Include_closes_reader() - { - using var context = CreateContext(); - var customer = await context.Set().Include(c => c.Orders).FirstOrDefaultAsync(); - var products = await context.Products.ToListAsync(); - - Assert.NotNull(customer); - Assert.NotNull(products); - } - - [ConditionalFact] - public virtual async Task Include_collection_alias_generation() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Include(o => o.OrderDetails) - .ToListAsync(); - - Assert.Equal(830, orders.Count); - } - - [ConditionalFact] - public virtual async Task Include_collection_and_reference() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Include(o => o.OrderDetails) - .Include(o => o.Customer) - .ToListAsync(); - - Assert.Equal(830, orders.Count); - } - - [ConditionalFact] - public virtual async Task Include_collection_as_no_tracking() - { - using var context = CreateContext(); - var customers - = await context.Set() - .Include(c => c.Orders) - .AsNoTracking() - .ToListAsync(); - - Assert.Equal(91, customers.Count); - Assert.Equal(830, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Empty(context.ChangeTracker.Entries()); - } - - [ConditionalFact] - public virtual async Task Include_collection_as_no_tracking2() - { - using var context = CreateContext(); - var customers - = await context.Set() - .AsNoTracking() - .OrderBy(c => c.CustomerID) - .Take(5) - .Include(c => c.Orders) - .ToListAsync(); - - Assert.Equal(5, customers.Count); - Assert.Equal(48, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Empty(context.ChangeTracker.Entries()); - } - - [ConditionalFact] - public virtual async Task Include_collection_dependent_already_tracked() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Where(o => o.CustomerID == "ALFKI") - .ToListAsync(); - - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - - var customer - = await context.Set() - .Include(c => c.Orders) - .SingleAsync(c => c.CustomerID == "ALFKI"); - - Assert.Equal(orders, customer.Orders, LegacyReferenceEqualityComparer.Instance); - Assert.Equal(6, customer.Orders.Count); - Assert.True(customer.Orders.All(o => o.Customer != null)); - Assert.Equal(6 + 1, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_dependent_already_tracked_as_no_tracking() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Where(o => o.CustomerID == "ALFKI") - .ToListAsync(); - - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - - var customer - = await context.Set() - .Include(c => c.Orders) - .AsNoTracking() - .SingleAsync(c => c.CustomerID == "ALFKI"); - - Assert.NotEqual(orders, customer.Orders, LegacyReferenceEqualityComparer.Instance); - Assert.Equal(6, customer.Orders.Count); - Assert.True(customer.Orders.All(o => o.Customer != null)); - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_on_additional_from_clause() - { - using var context = CreateContext(); - var customers - = await (from c1 in context.Set().OrderBy(c => c.CustomerID).Take(5) - from c2 in context.Set().Include(c => c.Orders) - select c2) - .ToListAsync(); - - Assert.Equal(455, customers.Count); - Assert.Equal(4150, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(455 + 466, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_on_additional_from_clause_no_tracking() - { - using var context = CreateContext(); - var customers - = await (from c1 in context.Set().OrderBy(c => c.CustomerID).Take(5) - from c2 in context.Set().AsNoTracking().Include(c => c.Orders) - select c2) - .ToListAsync(); - - Assert.Equal(455, customers.Count); - Assert.Equal(4150, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Empty(context.ChangeTracker.Entries()); - } - - [ConditionalFact] - public virtual async Task Include_collection_on_additional_from_clause_with_filter() - { - using var context = CreateContext(); - var customers - = await (from c1 in context.Set() - from c2 in context.Set() - .Include(c => c.Orders) - .Where(c => c.CustomerID == "ALFKI") - select c2) - .ToListAsync(); - - Assert.Equal(91, customers.Count); - Assert.Equal(546, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_on_additional_from_clause2() - { - using var context = CreateContext(); - var customers - = await (from c1 in context.Set().OrderBy(c => c.CustomerID).Take(5) - from c2 in context.Set().Include(c => c.Orders) - select c1) - .ToListAsync(); - - Assert.Equal(455, customers.Count); - Assert.True(customers.All(c => c.Orders == null)); - Assert.Equal(5, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_on_join_clause_with_filter() - { - using var context = CreateContext(); - var customers - = await (from c in context.Set().Include(c => c.Orders) - join o in context.Set() on c.CustomerID equals o.CustomerID - where c.CustomerID == "ALFKI" - select c) - .ToListAsync(); - - Assert.Equal(6, customers.Count); - Assert.Equal(36, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_on_join_clause_with_order_by_and_filter() - { - using var context = CreateContext(); - var customers - = await (from c in context.Set().Include(c => c.Orders) - join o in context.Set() on c.CustomerID equals o.CustomerID - where c.CustomerID == "ALFKI" - orderby c.City - select c) - .ToListAsync(); - - Assert.Equal(6, customers.Count); - Assert.Equal(36, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_order_by_key() - { - using var context = CreateContext(); - var customers - = await context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .ToListAsync(); - - Assert.Equal(91, customers.Count); - Assert.Equal(830, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(91 + 830, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_order_by_non_key() - { - using var context = CreateContext(); - var customers - = await context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.City) - .ToListAsync(); - - Assert.Equal(91, customers.Count); - Assert.Equal(830, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(91 + 830, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_principal_already_tracked() - { - using var context = CreateContext(); - var customer1 - = await context.Set() - .SingleAsync(c => c.CustomerID == "ALFKI"); - - Assert.Single(context.ChangeTracker.Entries()); - - var customer2 - = await context.Set() - .Include(c => c.Orders) - .SingleAsync(c => c.CustomerID == "ALFKI"); - - Assert.Same(customer1, customer2); - Assert.Equal(6, customer2.Orders.Count); - Assert.True(customer2.Orders.All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_principal_already_tracked_as_no_tracking() - { - using var context = CreateContext(); - var customer1 - = await context.Set() - .SingleAsync(c => c.CustomerID == "ALFKI"); - - Assert.Single(context.ChangeTracker.Entries()); - - var customer2 - = await context.Set() - .Include(c => c.Orders) - .AsNoTracking() - .SingleAsync(c => c.CustomerID == "ALFKI"); - - Assert.Null(customer1.Orders); - Assert.Equal(6, customer2.Orders.Count); - Assert.True(customer2.Orders.All(o => o.Customer != null)); - Assert.Single(context.ChangeTracker.Entries()); - } - - [ConditionalFact] - public virtual async Task Include_collection_single_or_default_no_result() - { - using var context = CreateContext(); - var customer - = await context.Set() - .Include(c => c.Orders) - .SingleOrDefaultAsync(c => c.CustomerID == "ALFKI ?"); - - Assert.Null(customer); - } - - [ConditionalFact] - public virtual async Task Include_collection_when_projection() - { - using var context = CreateContext(); - var productIds - = await context.Set() - .Include(c => c.Orders) - .Select(c => c.CustomerID) - .ToListAsync(); - - Assert.Equal(91, productIds.Count); - Assert.Empty(context.ChangeTracker.Entries()); - } - - [ConditionalFact] - public virtual async Task Include_collection_with_filter() - { - using var context = CreateContext(); - var customers - = await context.Set() - .Include(c => c.Orders) - .Where(c => c.CustomerID == "ALFKI") - .ToListAsync(); - - Assert.Single(customers); - Assert.Equal(6, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_collection_with_filter_reordered() - { - using var context = CreateContext(); - var customers - = await context.Set() - .Where(c => c.CustomerID == "ALFKI") - .Include(c => c.Orders) - .ToListAsync(); - - Assert.Single(customers); - Assert.Equal(6, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_duplicate_collection() - { - using var context = CreateContext(); - var customers - = await (from c1 in context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .Take(2) - from c2 in context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .Skip(2) - .Take(2) - select new { c1, c2 }) - .ToListAsync(); - - Assert.Equal(4, customers.Count); - Assert.Equal(20, customers.SelectMany(c => c.c1.Orders).Count()); - Assert.True(customers.SelectMany(c => c.c1.Orders).All(o => o.Customer != null)); - Assert.Equal(40, customers.SelectMany(c => c.c2.Orders).Count()); - Assert.True(customers.SelectMany(c => c.c2.Orders).All(o => o.Customer != null)); - Assert.Equal(34, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_duplicate_collection_result_operator() - { - using var context = CreateContext(); - var customers - = await (from c1 in context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .Take(2) - from c2 in context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .Skip(2) - .Take(2) - select new { c1, c2 }) - .Take(1) - .ToListAsync(); - - Assert.Single(customers); - Assert.Equal(6, customers.SelectMany(c => c.c1.Orders).Count()); - Assert.True(customers.SelectMany(c => c.c1.Orders).All(o => o.Customer != null)); - Assert.Equal(7, customers.SelectMany(c => c.c2.Orders).Count()); - Assert.True(customers.SelectMany(c => c.c2.Orders).All(o => o.Customer != null)); - Assert.Equal(15, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_duplicate_collection_result_operator2() - { - using var context = CreateContext(); - var customers - = await (from c1 in context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .Take(2) - from c2 in context.Set() - .OrderBy(c => c.CustomerID) - .Skip(2) - .Take(2) - select new { c1, c2 }) - .Take(1) - .ToListAsync(); - - Assert.Single(customers); - Assert.Equal(6, customers.SelectMany(c => c.c1.Orders).Count()); - Assert.True(customers.SelectMany(c => c.c1.Orders).All(o => o.Customer != null)); - Assert.True(customers.All(c => c.c2.Orders == null)); - Assert.Equal(8, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_duplicate_reference() - { - using var context = CreateContext(); - var orders - = await (from o1 in context.Set() - .Include(o => o.Customer) - .OrderBy(o => o.CustomerID) - .ThenBy(o => o.OrderID) - .Take(2) - from o2 in context.Set() - .Include(o => o.Customer) - .OrderBy(o => o.CustomerID) - .ThenBy(o => o.OrderID) - .Skip(2) - .Take(2) - select new { o1, o2 }) - .ToListAsync(); - - Assert.Equal(4, orders.Count); - Assert.True(orders.All(o => o.o1.Customer != null)); - Assert.True(orders.All(o => o.o2.Customer != null)); - Assert.Single(orders.Select(o => o.o1.Customer).Distinct()); - Assert.Single(orders.Select(o => o.o2.Customer).Distinct()); - Assert.Equal(5, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_duplicate_reference2() - { - using var context = CreateContext(); - var orders - = await (from o1 in context.Set() - .Include(o => o.Customer) - .OrderBy(o => o.OrderID) - .Take(2) - from o2 in context.Set() - .OrderBy(o => o.OrderID) - .Skip(2) - .Take(2) - select new { o1, o2 }) - .ToListAsync(); - - Assert.Equal(4, orders.Count); - Assert.True(orders.All(o => o.o1.Customer != null)); - Assert.True(orders.All(o => o.o2.Customer == null)); - Assert.Equal(2, orders.Select(o => o.o1.Customer).Distinct().Count()); - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_duplicate_reference3() - { - using var context = CreateContext(); - var orders - = await (from o1 in context.Set() - .OrderBy(o => o.OrderID) - .Take(2) - from o2 in context.Set() - .OrderBy(o => o.OrderID) - .Include(o => o.Customer) - .Skip(2) - .Take(2) - select new { o1, o2 }) - .ToListAsync(); - - Assert.Equal(4, orders.Count); - Assert.True(orders.All(o => o.o1.Customer == null)); - Assert.True(orders.All(o => o.o2.Customer != null)); - Assert.Equal(2, orders.Select(o => o.o2.Customer).Distinct().Count()); - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_multi_level_reference_and_collection_predicate() - { - using var context = CreateContext(); - var order - = await context.Set() - .Include(o => o.Customer.Orders) - .SingleAsync(o => o.OrderID == 10248); - - Assert.NotNull(order.Customer); - Assert.True(order.Customer.Orders.All(o => o != null)); - } - - [ConditionalFact] - public virtual async Task Include_collection_with_client_filter() - { - using var context = CreateContext(); - Assert.Contains( - CoreStrings.TranslationFailedWithDetails( - "", - CoreStrings.QueryUnableToTranslateMember(nameof(Customer.IsLondon), nameof(Customer))).Substring(21), - (await Assert.ThrowsAsync( - () => context.Set() - .Include(c => c.Orders) - .Where(c => c.IsLondon) - .ToListAsync())).Message); - } - - [ConditionalFact] - public virtual async Task Include_multi_level_collection_and_then_include_reference_predicate() - { - using var context = CreateContext(); - var order - = await context.Set() - .Include(o => o.OrderDetails).ThenInclude(od => od.Product) - .SingleAsync(o => o.OrderID == 10248); - - Assert.NotNull(order.OrderDetails); - Assert.True(order.OrderDetails.Count > 0); - Assert.True(order.OrderDetails.All(od => od.Product != null)); - } - - [ConditionalFact] - public virtual async Task Include_multiple_references() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(o => o.Order) - .Include(o => o.Product) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(o => o.Order != null)); - Assert.True(orderDetails.All(o => o.Product != null)); - Assert.Equal(830, orderDetails.Select(o => o.Order).Distinct().Count()); - Assert.True(orderDetails.Select(o => o.Product).Distinct().Any()); - } - - [ConditionalFact] - public virtual async Task Include_multiple_references_and_collection_multi_level() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Order.Customer.Orders) - .Include(od => od.Product) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - } - - [ConditionalFact] - public virtual async Task Include_multiple_references_and_collection_multi_level_reverse() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Product) - .Include(od => od.Order.Customer.Orders) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - } - - [ConditionalFact] - public virtual async Task Include_multiple_references_multi_level() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Order.Customer) - .Include(od => od.Product) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - } - - [ConditionalFact] - public virtual async Task Include_multiple_references_multi_level_reverse() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Product) - .Include(od => od.Order.Customer) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - } - - [ConditionalFact] - public virtual async Task Include_reference() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Include(o => o.Customer) - .ToListAsync(); - - Assert.Equal(830, orders.Count); - Assert.True(orders.All(o => o.Customer != null)); - Assert.Equal(89, orders.Select(o => o.Customer).Distinct().Count()); - Assert.Equal(830 + 89, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_reference_alias_generation() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Include(o => o.Order) - .ToListAsync(); - - Assert.True(orders.Count > 0); - } - - [ConditionalFact] - public virtual async Task Include_reference_and_collection() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Include(o => o.Customer) - .Include(o => o.OrderDetails) - .ToListAsync(); - - Assert.Equal(830, orders.Count); - } - - [ConditionalFact] - public virtual async Task Include_reference_as_no_tracking() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Include(o => o.Customer) - .AsNoTracking() - .ToListAsync(); - - Assert.Equal(830, orders.Count); - Assert.True(orders.All(o => o.Customer != null)); - Assert.Empty(context.ChangeTracker.Entries()); - } - - [ConditionalFact] - public virtual async Task Include_reference_dependent_already_tracked() - { - using var context = CreateContext(); - var orders1 - = await context.Set() - .Where(o => o.CustomerID == "ALFKI") - .ToListAsync(); - - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - - var orders2 - = await context.Set() - .Include(o => o.Customer) - .ToListAsync(); - - Assert.True(orders1.All(o1 => orders2.Contains(o1, LegacyReferenceEqualityComparer.Instance))); - Assert.True(orders2.All(o => o.Customer != null)); - Assert.Equal(830 + 89, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_reference_single_or_default_when_no_result() - { - using var context = CreateContext(); - var order - = await context.Set() - .Include(o => o.Customer) - .SingleOrDefaultAsync(o => o.OrderID == -1); - - Assert.Null(order); - } - - [ConditionalFact] - public virtual async Task Include_reference_when_projection() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Include(o => o.Customer) - .Select(o => o.CustomerID) - .ToListAsync(); - - Assert.Equal(830, orders.Count); - Assert.Empty(context.ChangeTracker.Entries()); - } - - [ConditionalFact] - public virtual async Task Include_reference_with_filter() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Include(o => o.Customer) - .Where(o => o.CustomerID == "ALFKI") - .ToListAsync(); - - Assert.Equal(6, orders.Count); - Assert.True(orders.All(o => o.Customer != null)); - Assert.Single(orders.Select(o => o.Customer).Distinct()); - Assert.Equal(6 + 1, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_reference_with_filter_reordered() - { - using var context = CreateContext(); - var orders - = await context.Set() - .Where(o => o.CustomerID == "ALFKI") - .Include(o => o.Customer) - .ToListAsync(); - - Assert.Equal(6, orders.Count); - Assert.True(orders.All(o => o.Customer != null)); - Assert.Single(orders.Select(o => o.Customer).Distinct()); - Assert.Equal(6 + 1, context.ChangeTracker.Entries().Count()); - } - - [ConditionalFact] - public virtual async Task Include_references_and_collection_multi_level() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Order.Customer.Orders) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - } - - [ConditionalFact] - public virtual async Task Include_collection_then_include_collection() - { - using var context = CreateContext(); - var customers - = await context.Set() - .Include(c => c.Orders).ThenInclude(o => o.OrderDetails) - .ToListAsync(); - - Assert.Equal(91, customers.Count); - Assert.True(customers.All(c => c.Orders != null)); - Assert.True(customers.All(c => c.Orders.All(o => o.OrderDetails != null))); - } - - [ConditionalFact] - public virtual async Task Include_collection_then_include_collection_then_include_reference() - { - using var context = CreateContext(); - var customers - = await context.Set() - .Include(c => c.Orders).ThenInclude(o => o.OrderDetails).ThenInclude(od => od.Product) - .ToListAsync(); - - Assert.Equal(91, customers.Count); - Assert.True(customers.All(c => c.Orders != null)); - Assert.True(customers.All(c => c.Orders.All(o => o.OrderDetails != null))); - } - - [ConditionalFact] - public virtual async Task Include_collection_then_include_collection_predicate() - { - using var context = CreateContext(); - var customer - = await context.Set() - .Include(c => c.Orders).ThenInclude(o => o.OrderDetails) - .SingleOrDefaultAsync(c => c.CustomerID == "ALFKI"); - - Assert.NotNull(customer); - Assert.Equal(6, customer.Orders.Count); - Assert.True(customer.Orders.SelectMany(o => o.OrderDetails).Count() >= 6); - } - - [ConditionalFact] - public virtual async Task Include_references_and_collection_multi_level_predicate() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Order.Customer.Orders) - .Where(od => od.OrderID == 10248) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - } - - [ConditionalFact] - public virtual async Task Include_references_multi_level() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Order.Customer) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - } - - [ConditionalFact] - public virtual async Task Include_multi_level_reference_then_include_collection_predicate() - { - using var context = CreateContext(); - var order - = await context.Set() - .Include(o => o.Customer).ThenInclude(c => c.Orders) - .SingleAsync(o => o.OrderID == 10248); - - Assert.NotNull(order.Customer); - Assert.True(order.Customer.Orders.All(o => o != null)); - } - - [ConditionalFact] - public virtual async Task Include_multiple_references_then_include_collection_multi_level() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Order).ThenInclude(o => o.Customer).ThenInclude(c => c.Orders) - .Include(od => od.Product) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - } - - [ConditionalFact] - public virtual async Task Include_multiple_references_then_include_collection_multi_level_reverse() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Product) - .Include(od => od.Order).ThenInclude(o => o.Customer).ThenInclude(c => c.Orders) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - } - - [ConditionalFact] - public virtual async Task Include_multiple_references_then_include_multi_level() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Order).ThenInclude(o => o.Customer) - .Include(od => od.Product) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - } - - [ConditionalFact] - public virtual async Task Include_multiple_references_then_include_multi_level_reverse() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Product) - .Include(od => od.Order).ThenInclude(o => o.Customer) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - } - - [ConditionalFact] - public virtual async Task Include_references_then_include_collection_multi_level() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Order).ThenInclude(o => o.Customer).ThenInclude(c => c.Orders) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - } - - [ConditionalFact] - public virtual async Task Include_references_then_include_collection_multi_level_predicate() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Order).ThenInclude(o => o.Customer).ThenInclude(c => c.Orders) - .Where(od => od.OrderID == 10248) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - } - - [ConditionalFact] - public virtual async Task Include_references_then_include_multi_level() - { - using var context = CreateContext(); - var orderDetails - = await context.Set() - .Include(od => od.Order).ThenInclude(o => o.Customer) - .ToListAsync(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - } - - protected NorthwindContext CreateContext() => Fixture.CreateContext(); - } -} diff --git a/test/EFCore.Specification.Tests/Query/NorthwindIncludeQueryTestBase.cs b/test/EFCore.Specification.Tests/Query/NorthwindIncludeQueryTestBase.cs index 312de559ef9..e85a161ce14 100644 --- a/test/EFCore.Specification.Tests/Query/NorthwindIncludeQueryTestBase.cs +++ b/test/EFCore.Specification.Tests/Query/NorthwindIncludeQueryTestBase.cs @@ -4,8 +4,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; -using System.Reflection; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Internal; @@ -20,1273 +18,536 @@ namespace Microsoft.EntityFrameworkCore.Query { - public abstract class NorthwindIncludeQueryTestBase : IClassFixture + public abstract class NorthwindIncludeQueryTestBase : QueryTestBase where TFixture : NorthwindQueryFixtureBase, new() { - protected NorthwindIncludeQueryTestBase(TFixture fixture) => Fixture = fixture; - - protected TFixture Fixture { get; } - - [ConditionalFact] - public virtual void Include_reference_invalid() + protected NorthwindIncludeQueryTestBase(TFixture fixture) + : base(fixture) { - Assert.Throws( - () => - { - using var context = CreateContext(); - return context.Set() - .Include(o => o.Customer.CustomerID) - .ToList(); - }); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_and_collection_order_by(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_and_collection_order_by(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Customer.Orders") - .OrderBy(o => o.OrderID) - .ToList() - : context.Set() - .Include(o => o.Customer.Orders) - .OrderBy(o => o.OrderID) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(o => o.Customer != null)); - Assert.True(orderDetails.All(o => o.Customer.Orders != null)); + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Customer.Orders).OrderBy(o => o.OrderID), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(o => o.Customer), new ExpectedInclude(c => c.Orders, "Customer")), + assertOrder: true, + entryCount: 919); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_references_then_include_collection(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_references_then_include_collection(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Set() - .Include("Customer.Orders") - .ToList() - : context.Set() - .Include(o => o.Customer).ThenInclude(c => c.Orders) - .ToList(); - - Assert.True(orders.Count > 0); - Assert.True(orders.All(od => od.Customer != null)); - Assert.True(orders.All(od => od.Customer.Orders != null)); + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Customer).ThenInclude(c => c.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(o => o.Customer), + new ExpectedInclude(c => c.Orders, "Customer")), + entryCount: 919); } - [ConditionalFact(Skip = "issue #15312")] - public virtual void Include_bad_navigation_property() + [ConditionalTheory(Skip = "issue #15312")] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_property_after_navigation(bool async) { - using var context = CreateContext(); Assert.Equal( CoreStrings.IncludeBadNavigation("CustomerID", nameof(Customer)), - Assert.Throws( - () => context.Set().Include("Customer.CustomerID").ToList()).Message); + (await Assert.ThrowsAsync( + () => AssertQuery( + async, + ss => ss.Set().Include(o => o.Customer.CustomerID)))).Message); } - [ConditionalFact(Skip = "issue #15312")] - public virtual void Include_bad_navigation_property_simple() + [ConditionalTheory(Skip = "issue #15312")] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_property(bool async) + { + Assert.Equal( + CoreStrings.IncludeBadNavigation("OrderDate", nameof(Order)), + (await Assert.ThrowsAsync( + () => AssertQuery( + async, + ss => ss.Set().Include(o => o.OrderDate)))).Message); + } + + [ConditionalTheory(Skip = "issue #15312")] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_non_existing_navigation(bool async) { - using var context = CreateContext(); Assert.Equal( CoreStrings.IncludeBadNavigation("ArcticMonkeys", nameof(Order)), - Assert.Throws( - () => context.Set().Include("ArcticMonkeys").ToList()).Message); - } - - [ConditionalFact(Skip = "issue #15312")] - public virtual void Include_property_expression_invalid() - { - var anonymousType = new { Customer = default(Customer), OrderDetails = default(ICollection) }.GetType(); - var lambdaExpression = Expression.Lambda( - Expression.New( - anonymousType.GetTypeInfo().DeclaredConstructors.First(), - new List - { - Expression.MakeMemberAccess( - Expression.Parameter(typeof(Order), "o"), - typeof(Order).GetTypeInfo().DeclaredMembers.Single(m => m.Name == "Customer")), - Expression.MakeMemberAccess( - Expression.Parameter(typeof(Order), "o"), - typeof(Order).GetTypeInfo().DeclaredMembers.Single(m => m.Name == "OrderDetails")) - }, - anonymousType.GetTypeInfo().DeclaredMembers.Single(m => m.Name == "Customer"), - anonymousType.GetTypeInfo().DeclaredMembers.Single(m => m.Name == "OrderDetails") - ), - Expression.Parameter(typeof(Order), "o")); + (await Assert.ThrowsAsync( + () => AssertQuery( + async, + ss => ss.Set().Include("ArcticMonkeys")))).Message); + } + [ConditionalTheory(Skip = "issue #15312")] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_property_expression_invalid(bool async) + { Assert.Equal( - CoreStrings.InvalidIncludeExpression(lambdaExpression.Body.ToString()), - Assert.Throws( - () => - { - using var context = CreateContext(); - context.Set() - .Include( - o => new { o.Customer, o.OrderDetails }) - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - .ToList(); - }).Message); + CoreStrings.InvalidIncludeExpression(" "), + (await Assert.ThrowsAsync( + () => AssertQuery( + async, + ss => ss.Set().Include(o => new { o.Customer, o.OrderDetails })))).Message); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Then_include_collection_order_by_collection_column(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Then_include_collection_order_by_collection_column(bool async) { - using var context = CreateContext(); - var customer - = useString - ? context.Set() - .Include("Orders.OrderDetails") - .Where(c => c.CustomerID.StartsWith("W")) - .OrderByDescending(c => c.Orders.OrderByDescending(oo => oo.OrderDate).FirstOrDefault().OrderDate) - .FirstOrDefault() - : context.Set() + return AssertFirstOrDefault( + async, + ss => ss.Set() .Include(c => c.Orders) .ThenInclude(o => o.OrderDetails) .Where(c => c.CustomerID.StartsWith("W")) - .OrderByDescending(c => c.Orders.OrderByDescending(oo => oo.OrderDate).FirstOrDefault().OrderDate) - .FirstOrDefault(); - - Assert.NotNull(customer); - Assert.Equal("WHITC", customer.CustomerID); - Assert.NotNull(customer.Orders); - Assert.Equal(14, customer.Orders.Count); - Assert.NotNull(customer.Orders.First().OrderDetails); - Assert.Equal(2, customer.Orders.First().OrderDetails.Count); - Assert.NotNull(customer.Orders.Last().OrderDetails); - Assert.Equal(3, customer.Orders.Last().OrderDetails.Count); - - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: true, - productLoaded: false); - } - - [ConditionalFact(Skip = "issue#15312")] - public virtual void Then_include_property_expression_invalid() - { - var anonymousType = new { Customer = default(Customer), OrderDetails = default(ICollection) }.GetType(); - var lambdaExpression = Expression.Lambda( - Expression.New( - anonymousType.GetTypeInfo().DeclaredConstructors.First(), - new List - { - Expression.MakeMemberAccess( - Expression.Parameter(typeof(Order), "o"), - typeof(Order).GetTypeInfo().DeclaredMembers.Single(m => m.Name == "Customer")), - Expression.MakeMemberAccess( - Expression.Parameter(typeof(Order), "o"), - typeof(Order).GetTypeInfo().DeclaredMembers.Single(m => m.Name == "OrderDetails")) - }, - anonymousType.GetTypeInfo().DeclaredMembers.Single(m => m.Name == "Customer"), - anonymousType.GetTypeInfo().DeclaredMembers.Single(m => m.Name == "OrderDetails") - ), - Expression.Parameter(typeof(Order), "o")); + .OrderByDescending(c => c.Orders.OrderByDescending(oo => oo.OrderDate).FirstOrDefault().OrderDate), + asserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(c => c.Orders), + new ExpectedInclude(o => o.OrderDetails, "Orders")), + entryCount: 55); + } + [ConditionalTheory(Skip = "issue#15312")] + [MemberData(nameof(IsAsyncData))] + public virtual async Task Then_include_property_expression_invalid(bool async) + { Assert.Equal( - CoreStrings.InvalidIncludeExpression(lambdaExpression.Body.ToString()), - Assert.Throws( - () => - { - using var context = CreateContext(); - context.Set() + CoreStrings.InvalidIncludeExpression(" "), + (await Assert.ThrowsAsync( + () => AssertQuery( + async, + ss => ss.Set() .Include(o => o.Orders) - .ThenInclude( - o => new { o.Customer, o.OrderDetails }) - // ReSharper disable once ReturnValueOfPureMethodIsNotUsed - .ToList(); - }).Message); + .ThenInclude(o => new { o.Customer, o.OrderDetails })))).Message); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_closes_reader(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_closes_reader(bool async) { using var context = CreateContext(); - var customer = useString - ? context.Set().Include("Orders").FirstOrDefault() - : context.Set().Include(c => c.Orders).FirstOrDefault(); - - var products = context.Products.ToList(); - - Assert.NotNull(customer); - Assert.NotNull(products); + if (async) + { + Assert.NotNull(await context.Set().Include(c => c.Orders).FirstOrDefaultAsync()); + Assert.NotNull(await context.Set().ToListAsync()); + } + else + { + Assert.NotNull(context.Set().Include(c => c.Orders).FirstOrDefault()); + Assert.NotNull(context.Set().ToList()); + } } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_when_result_operator(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_when_result_operator(bool async) { - using var context = CreateContext(); - var any - = useString - ? context.Set() - .Include("Orders") - .Any() - : context.Set() - .Include(c => c.Orders) - .Any(); - - Assert.True(any); + return AssertAny( + async, + ss => ss.Set().Include(c => c.Orders)); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Include("Orders") - .ToList() - : context.Set() - .Include(c => c.Orders) - .ToList(); - - Assert.Equal(91, customers.Count); - Assert.Equal(830, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(91 + 830, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 921); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_then_reference(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_then_reference(bool async) { - using var context = CreateContext(); - var products - = useString - ? context.Products - .Include("OrderDetails.Order") - .ToList() - : context.Products - .Include(p => p.OrderDetails) - .ThenInclude(od => od.Order) - .ToList(); - - Assert.Equal(77, products.Count); - Assert.Equal(2155, products.SelectMany(p => p.OrderDetails).Count()); - Assert.Equal(2155, products.SelectMany(p => p.OrderDetails).Count(od => od.Order != null)); - Assert.Equal(77 + 2155 + 830, context.ChangeTracker.Entries().Count()); - - foreach (var product in products) - { - CheckIsLoaded( - context, - product, - orderDetailsLoaded: true, - orderLoaded: true); - } + return AssertQuery( + async, + ss => ss.Set().Include(p => p.OrderDetails).ThenInclude(od => od.Order), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(p => p.OrderDetails), + new ExpectedInclude(od => od.Order, "OrderDetails")), + entryCount: 3062); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_last(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_with_last(bool async) { - using var context = CreateContext(); - var customer - = useString - ? context.Set() - .Include("Orders") - .OrderBy(c => c.CompanyName) - .Last() - : context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CompanyName) - .Last(); - - Assert.NotNull(customer); - Assert.Equal(7, customer.Orders.Count); - Assert.Equal(8, context.ChangeTracker.Entries().Count()); + return AssertLast( + async, + ss => ss.Set().Include(c => c.Orders).OrderBy(c => c.CompanyName), + asserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 8); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_last_no_orderby(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_collection_with_last_no_orderby(bool async) { - using var context = CreateContext(); Assert.Equal( CoreStrings.LastUsedWithoutOrderBy(nameof(Enumerable.Last)), - Assert.Throws( - () => useString - ? context.Set().Include("Orders").Last() - : context.Set().Include(c => c.Orders).Last()).Message); - } - - [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_skip_no_order_by(bool useString) - { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Skip(10) - .Include("Orders") - .ToList() - : context.Set() - .Skip(10) - .Include(c => c.Orders) - .ToList(); - - Assert.Equal(81, customers.Count); - Assert.True(customers.All(c => c.Orders != null)); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + (await Assert.ThrowsAsync( + () => AssertLast( + async, + ss => ss.Set().Include(c => c.Orders), + entryCount: 8))).Message); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_take_no_order_by(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_skip_no_order_by(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Take(10) - .Include("Orders") - .ToList() - : context.Set() - .Take(10) - .Include(c => c.Orders) - .ToList(); - - Assert.Equal(10, customers.Count); - Assert.True(customers.All(c => c.Orders != null)); + return AssertQuery( + async, + ss => ss.Set().Skip(10).Include(c => c.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 811); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_skip_take_no_order_by(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_take_no_order_by(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Skip(10) - .Take(5) - .Include("Orders") - .ToList() - : context.Set() - .Skip(10) - .Take(5) - .Include(c => c.Orders) - .ToList(); - - Assert.Equal(5, customers.Count); - Assert.True(customers.All(c => c.Orders != null)); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Take(10).Include(c => c.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 110); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_list(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_skip_take_no_order_by(bool async) { - using var context = CreateContext(); - var products - = useString - ? context.Set() - .Include("OrderDetails.Order") - .ToList() - : context.Set() - .Include(p => p.OrderDetails).ThenInclude(od => od.Order) - .ToList(); - - Assert.Equal(77, products.Count); - - foreach (var product in products) - { - CheckIsLoaded( - context, - product, - orderDetailsLoaded: true, - orderLoaded: true); - } + return AssertQuery( + async, + ss => ss.Set().Skip(10).Take(5).Include(c => c.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 35); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_alias_generation(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_list(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Set() - .Include("OrderDetails") - .ToList() - : context.Set() - .Include(o => o.OrderDetails) - .ToList(); - - Assert.Equal(830, orders.Count); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(p => p.OrderDetails).ThenInclude(od => od.Order), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(p => p.OrderDetails), + new ExpectedInclude(od => od.Order, "OrderDetails")), + entryCount: 3062); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_and_reference(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_alias_generation(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Set() - .Include("OrderDetails") - .Include("Customer") - .ToList() - : context.Set() - .Include(o => o.OrderDetails) - .Include(o => o.Customer) - .ToList(); - - Assert.Equal(830, orders.Count); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.OrderDetails), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(o => o.OrderDetails)), + entryCount: 2985); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_as_no_tracking(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_and_reference(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Include("Orders") - .AsNoTracking() - .ToList() - : context.Set() - .Include(c => c.Orders) - .AsNoTracking() - .ToList(); - - Assert.Equal(91, customers.Count); - Assert.Equal(830, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Empty(context.ChangeTracker.Entries()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: false, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.OrderDetails).Include(o => o.Customer), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(o => o.OrderDetails), new ExpectedInclude(o => o.Customer)), + entryCount: 3074); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_as_no_tracking2(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_orderby_take(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .AsNoTracking() - .OrderBy(c => c.CustomerID) - .Take(5) - .Include("Orders") - .ToList() - : context.Set() - .AsNoTracking() - .OrderBy(c => c.CustomerID) - .Take(5) - .Include(c => c.Orders) - .ToList(); - - Assert.Equal(5, customers.Count); - Assert.Equal(48, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Empty(context.ChangeTracker.Entries()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: false, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().OrderBy(c => c.CustomerID).Take(5).Include(c => c.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 53); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_dependent_already_tracked(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_collection_dependent_already_tracked(bool async) { using var context = CreateContext(); - var orders - = context.Set() - .Where(o => o.CustomerID == "ALFKI") - .ToList(); - + var orders = context.Set().Where(o => o.CustomerID == "ALFKI").ToList(); Assert.Equal(6, context.ChangeTracker.Entries().Count()); var customer - = useString - ? context.Set() - .Include("Orders") - .Single(c => c.CustomerID == "ALFKI") + = async + ? await context.Set() + .Include(c => c.Orders) + .SingleAsync(c => c.CustomerID == "ALFKI") : context.Set() .Include(c => c.Orders) .Single(c => c.CustomerID == "ALFKI"); Assert.Equal(orders, customer.Orders, LegacyReferenceEqualityComparer.Instance); Assert.Equal(6, customer.Orders.Count); - Assert.True(customer.Orders.All(o => o.Customer != null)); + Assert.True(orders.All(o => ReferenceEquals(o.Customer, customer))); Assert.Equal(6 + 1, context.ChangeTracker.Entries().Count()); - - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } - - [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_dependent_already_tracked_as_no_tracking(bool useString) - { - using var context = CreateContext(); - var orders - = context.Set() - .Where(o => o.CustomerID == "ALFKI") - .ToList(); - - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - - var customer - = useString - ? context.Set() - .Include("Orders") - .AsNoTracking() - .Single(c => c.CustomerID == "ALFKI") - : context.Set() - .Include(c => c.Orders) - .AsNoTracking() - .Single(c => c.CustomerID == "ALFKI"); - - Assert.NotEqual(orders, customer.Orders, LegacyReferenceEqualityComparer.Instance); - Assert.Equal(6, customer.Orders.Count); - Assert.True(customer.Orders.All(o => o.Customer != null)); - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - - CheckIsLoaded( - context, - customer, - ordersLoaded: false, - orderDetailsLoaded: false, - productLoaded: false); - } - - [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_on_additional_from_clause(bool useString) - { - using var context = CreateContext(); - var customers - = useString - ? (from c1 in context.Set().OrderBy(c => c.CustomerID).Take(5) - from c2 in context.Set().Include("Orders") - select c2) - .ToList() - : (from c1 in context.Set().OrderBy(c => c.CustomerID).Take(5) - from c2 in context.Set().Include(c2 => c2.Orders) - select c2) - .ToList(); - - Assert.Equal(455, customers.Count); - Assert.Equal(4150, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(455 + 466, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_on_additional_from_clause_no_tracking(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_on_additional_from_clause(bool async) { - using var context = CreateContext(); - var customers - = useString - ? (from c1 in context.Set().OrderBy(c => c.CustomerID).Take(5) - from c2 in context.Set().AsNoTracking().Include(c => c.Orders) - select c2) - .ToList() - : (from c1 in context.Set().OrderBy(c => c.CustomerID).Take(5) - from c2 in context.Set().AsNoTracking().Include(c => c.Orders) - select c2) - .ToList(); - - Assert.Equal(455, customers.Count); - Assert.Equal(4150, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Empty(context.ChangeTracker.Entries()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: false, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => from c1 in ss.Set().OrderBy(c => c.CustomerID).Take(5) + from c2 in ss.Set().Include(c2 => c2.Orders) + select c2, + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 921); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_on_additional_from_clause_with_filter(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_on_additional_from_clause_with_filter(bool async) { - using var context = CreateContext(); - var customers - = useString - ? (from c1 in context.Set() - from c2 in context.Set() - .Include("Orders") - .Where(c => c.CustomerID == "ALFKI") - select c2) - .ToList() - : (from c1 in context.Set() - from c2 in context.Set() - .Include(c => c.Orders) - .Where(c => c.CustomerID == "ALFKI") - select c2) - .ToList(); - - Assert.Equal(91, customers.Count); - Assert.Equal(546, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => from c1 in ss.Set() + from c2 in ss.Set().Include(c => c.Orders).Where(c => c.CustomerID == "ALFKI") + select c2, + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 7); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_on_additional_from_clause2(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_on_additional_from_clause2(bool async) { - using var context = CreateContext(); - var customers - = useString - ? (from c1 in context.Set().OrderBy(c => c.CustomerID).Take(5) - from c2 in context.Set().Include("Orders") - select c1) - .ToList() - : (from c1 in context.Set().OrderBy(c => c.CustomerID).Take(5) - from c2 in context.Set().Include(c2 => c2.Orders) - select c1) - .ToList(); - - Assert.Equal(455, customers.Count); - Assert.True(customers.All(c => c.Orders == null)); - Assert.Equal(5, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: false, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => from c1 in ss.Set().OrderBy(c => c.CustomerID).Take(5) + from c2 in ss.Set().Include(c2 => c2.Orders) + select c1, + entryCount: 5); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_where_skip_take_projection(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_where_skip_take_projection(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.OrderDetails.Include("Order") - .Where(od => od.Quantity == 10) - .OrderBy(od => od.OrderID) - .ThenBy(od => od.ProductID) - .Skip(1) - .Take(2) - .Select( - od => - new { od.Order.CustomerID }) - .ToList() - : context.OrderDetails.Include(od => od.Order) + return AssertQuery( + async, + ss => ss.Set() + .Include(od => od.Order) .Where(od => od.Quantity == 10) .OrderBy(od => od.OrderID) .ThenBy(od => od.ProductID) .Skip(1) .Take(2) - .Select( - od => - new { od.Order.CustomerID }) - .ToList(); - - Assert.Equal(2, orders.Count); + .Select(od => new { od.Order.CustomerID })); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_join_clause_with_filter(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_with_join_clause_with_filter(bool async) { - using var context = CreateContext(); - var customers - = useString - ? (from c in context.Set().Include("Orders") - join o in context.Set() on c.CustomerID equals o.CustomerID - where c.CustomerID.StartsWith("F") - select c) - .ToList() - : (from c in context.Set().Include(c => c.Orders) - join o in context.Set() on c.CustomerID equals o.CustomerID - where c.CustomerID.StartsWith("F") - select c) - .ToList(); - - Assert.Equal(63, customers.Count); - Assert.Equal(769, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(7 + 63, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => from c in ss.Set().Include(c => c.Orders) + join o in ss.Set() on c.CustomerID equals o.CustomerID + where c.CustomerID.StartsWith("F") + select c, + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 70); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_left_join_clause_with_filter(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_with_left_join_clause_with_filter(bool async) { - using var context = CreateContext(); - var customers - = useString - ? (from c in context.Set().Include("Orders") - join o in context.Set() on c.CustomerID equals o.CustomerID into grouping - from o in grouping.DefaultIfEmpty() - where c.CustomerID.StartsWith("F") - select c) - .ToList() - : (from c in context.Set().Include(c => c.Orders) - join o in context.Set() on c.CustomerID equals o.CustomerID into grouping - from o in grouping.DefaultIfEmpty() - where c.CustomerID.StartsWith("F") - select c) - .ToList(); - - Assert.Equal(64, customers.Count); - Assert.Equal(769, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(8 + 63, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => from c in ss.Set().Include(c => c.Orders) + join o in ss.Set() on c.CustomerID equals o.CustomerID into grouping + from o in grouping.DefaultIfEmpty() + where c.CustomerID.StartsWith("F") + select c, + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 71); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_cross_join_clause_with_filter(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_with_cross_join_clause_with_filter(bool async) { - using var context = CreateContext(); - var customers - = useString - ? (from c in context.Set().Include("Orders") - from o in context.Set().OrderBy(o => o.OrderID).Take(5) - where c.CustomerID.StartsWith("F") - select c) - .ToList() - : (from c in context.Set().Include(c => c.Orders) - from o in context.Set().OrderBy(o => o.OrderID).Take(5) - where c.CustomerID.StartsWith("F") - select c) - .ToList(); - - Assert.Equal(40, customers.Count); - Assert.Equal(315, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(8 + 63, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => from c in ss.Set().Include(c => c.Orders) + from o in ss.Set().OrderBy(o => o.OrderID).Take(5) + where c.CustomerID.StartsWith("F") + select c, + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 71); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_cross_apply_with_filter(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_with_cross_apply_with_filter(bool async) { - using var context = CreateContext(); - var customers - = useString - ? (from c in context.Set().Include("Orders") - from o in context.Set().Where(o => o.CustomerID == c.CustomerID).OrderBy(o => c.CustomerID).Take(5) - where c.CustomerID.StartsWith("F") - select c) - .ToList() - : (from c in context.Set().Include(c => c.Orders) - from o in context.Set().Where(o => o.CustomerID == c.CustomerID).OrderBy(o => c.CustomerID).Take(5) - where c.CustomerID.StartsWith("F") - select c) - .ToList(); - - Assert.Equal(33, customers.Count); - Assert.Equal(309, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(7 + 63, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => from c in ss.Set().Include(c => c.Orders) + from o in ss.Set().Where(o => o.CustomerID == c.CustomerID).OrderBy(o => c.CustomerID).Take(5) + where c.CustomerID.StartsWith("F") + select c, + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 70); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_outer_apply_with_filter(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_with_outer_apply_with_filter(bool async) { - using var context = CreateContext(); - var customers - = useString - ? (from c in context.Set().Include("Orders") - from o in context.Set().Where(o => o.CustomerID == c.CustomerID) - .OrderBy(o => c.CustomerID).Take(5).DefaultIfEmpty() - where c.CustomerID.StartsWith("F") - select c) - .ToList() - : (from c in context.Set().Include(c => c.Orders) - from o in context.Set().Where(o => o.CustomerID == c.CustomerID) - .OrderBy(o => c.CustomerID).Take(5).DefaultIfEmpty() - where c.CustomerID.StartsWith("F") - select c) - .ToList(); - - Assert.Equal(34, customers.Count); - Assert.Equal(309, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(8 + 63, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => from c in ss.Set().Include(c => c.Orders) + from o in ss.Set().Where(o => o.CustomerID == c.CustomerID) + .OrderBy(o => c.CustomerID).Take(5).DefaultIfEmpty() + where c.CustomerID.StartsWith("F") + select c, + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 71); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_on_join_clause_with_order_by_and_filter(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_on_join_clause_with_order_by_and_filter(bool async) { - using var context = CreateContext(); - var customers - = useString - ? (from c in context.Set().Include("Orders") - join o in context.Set() on c.CustomerID equals o.CustomerID - where c.CustomerID == "ALFKI" - orderby c.City - select c) - .ToList() - : (from c in context.Set().Include(c => c.Orders) - join o in context.Set() on c.CustomerID equals o.CustomerID - where c.CustomerID == "ALFKI" - orderby c.City - select c) - .ToList(); - - Assert.Equal(6, customers.Count); - Assert.Equal(36, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => from c in ss.Set().Include(c => c.Orders) + join o in ss.Set() on c.CustomerID equals o.CustomerID + where c.CustomerID == "ALFKI" + orderby c.City + select c, + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + assertOrder: true, + entryCount: 7); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_order_by_collection_column(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_order_by_collection_column(bool async) { - using var context = CreateContext(); - var customer - = useString - ? context.Set() - .Include("Orders") - .Where(c => c.CustomerID.StartsWith("W")) - .OrderByDescending(c => c.Orders.OrderByDescending(oo => oo.OrderDate).FirstOrDefault().OrderDate) - .FirstOrDefault() - : context.Set() + return AssertFirstOrDefault( + async, + ss => ss.Set() .Include(c => c.Orders) .Where(c => c.CustomerID.StartsWith("W")) - .OrderByDescending(c => c.Orders.OrderByDescending(oo => oo.OrderDate).FirstOrDefault().OrderDate) - .FirstOrDefault(); - - Assert.NotNull(customer); - Assert.Equal("WHITC", customer.CustomerID); - Assert.NotNull(customer.Orders); - Assert.Equal(14, customer.Orders.Count); - - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); + .OrderByDescending(c => c.Orders.OrderByDescending(oo => oo.OrderDate).FirstOrDefault().OrderDate), + asserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 15); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_order_by_key(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_order_by_key(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Include("Orders") - .OrderBy(c => c.CustomerID) - .ToList() - : context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .ToList(); - - Assert.Equal(91, customers.Count); - Assert.Equal(830, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(91 + 830, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders).OrderBy(c => c.CustomerID), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + assertOrder: true, + entryCount: 921); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_order_by_non_key(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_order_by_non_key(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Include("Orders") - .OrderBy(c => c.City) - .ToList() - : context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.City) - .ToList(); - - Assert.Equal(91, customers.Count); - Assert.Equal(830, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(91 + 830, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders).OrderBy(c => c.PostalCode), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + assertOrder: true, + entryCount: 921); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_order_by_non_key_with_take(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_order_by_non_key_with_take(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Include("Orders") - .OrderBy(c => c.ContactTitle) - .Take(10) - .ToList() - : context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.ContactTitle) - .Take(10) - .ToList(); - - Assert.Equal(10, customers.Count); - Assert.Equal(116, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(10 + 116, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders).OrderBy(c => c.ContactTitle).Take(10), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 126); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_order_by_non_key_with_skip(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_order_by_non_key_with_skip(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Include("Orders") - .OrderBy(c => c.ContactTitle) - .Skip(10) - .ToList() - : context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.ContactTitle) - .Skip(10) - .ToList(); - - Assert.Equal(81, customers.Count); - Assert.Equal(714, customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).Count()); - Assert.True(customers.Where(c => c.Orders != null).SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(81, context.ChangeTracker.Entries().Count(e => e.Entity is Customer)); - Assert.Equal(714, context.ChangeTracker.Entries().Count(e => e.Entity is Order)); - Assert.Equal(81 + 714, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders).OrderBy(c => c.ContactTitle).Skip(10), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 795); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_order_by_non_key_with_first_or_default(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_order_by_non_key_with_first_or_default(bool async) { - using var context = CreateContext(); - var customer - = useString - ? context.Set() - .Include("Orders") - .OrderByDescending(c => c.CompanyName) - .FirstOrDefault() - : context.Set() - .Include(c => c.Orders) - .OrderByDescending(c => c.CompanyName) - .FirstOrDefault(); - - Assert.NotNull(customer); - Assert.Equal(7, customer.Orders.Count); - Assert.True(customer.Orders.All(o => o.Customer != null)); - Assert.Equal(1 + 7, context.ChangeTracker.Entries().Count()); - - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); + return AssertFirstOrDefault( + async, + ss => ss.Set().Include(c => c.Orders).OrderByDescending(c => c.CompanyName), + asserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 8); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_order_by_subquery(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_order_by_subquery(bool async) { - using var context = CreateContext(); - var customer - = useString - ? context.Set() - .Include("Orders") - .Where(c => c.CustomerID == "ALFKI") - .OrderBy(c => c.Orders.OrderBy(o => o.EmployeeID).Select(o => o.OrderDate).FirstOrDefault()) - .FirstOrDefault() - : context.Set() + return AssertFirstOrDefault( + async, + ss => ss.Set() .Include(c => c.Orders) .Where(c => c.CustomerID == "ALFKI") - .OrderBy(c => c.Orders.OrderBy(o => o.EmployeeID).Select(o => o.OrderDate).FirstOrDefault()) - .FirstOrDefault(); - - Assert.NotNull(customer); - Assert.NotNull(customer.Orders); - Assert.Equal(6, customer.Orders.Count); - - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); + .OrderBy(c => c.Orders.OrderBy(o => o.EmployeeID).Select(o => o.OrderDate).FirstOrDefault()), + asserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 7); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_principal_already_tracked(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_collection_principal_already_tracked(bool async) { using var context = CreateContext(); - var customer1 - = context.Set() - .Single(c => c.CustomerID == "ALFKI"); - + var customer1 = context.Set().Single(c => c.CustomerID == "ALFKI"); Assert.Single(context.ChangeTracker.Entries()); var customer2 - = useString - ? context.Set() - .Include("Orders") - .Single(c => c.CustomerID == "ALFKI") + = async + ? await context.Set() + .Include(c => c.Orders) + .SingleAsync(c => c.CustomerID == "ALFKI") : context.Set() .Include(c => c.Orders) .Single(c => c.CustomerID == "ALFKI"); @@ -1294,2634 +555,1067 @@ var customer2 Assert.Same(customer1, customer2); Assert.Equal(6, customer2.Orders.Count); Assert.True(customer2.Orders.All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); - - CheckIsLoaded( - context, - customer2, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); + Assert.Equal(7, context.ChangeTracker.Entries().Count()); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_principal_already_tracked_as_no_tracking(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_single_or_default_no_result(bool async) { - using var context = CreateContext(); - var customer1 - = context.Set() - .Single(c => c.CustomerID == "ALFKI"); - - Assert.Single(context.ChangeTracker.Entries()); - - var customer2 - = useString - ? context.Set() - .Include("Orders") - .AsNoTracking() - .Single(c => c.CustomerID == "ALFKI") - : context.Set() - .Include(c => c.Orders) - .AsNoTracking() - .Single(c => c.CustomerID == "ALFKI"); - - Assert.Equal(customer1.CustomerID, customer2.CustomerID); - Assert.Null(customer1.Orders); - Assert.Equal(6, customer2.Orders.Count); - Assert.True(customer2.Orders.All(o => o.Customer != null)); - Assert.Single(context.ChangeTracker.Entries()); - - CheckIsLoaded( - context, - customer2, - ordersLoaded: false, - orderDetailsLoaded: false, - productLoaded: false); + return AssertSingleOrDefault( + async, + ss => ss.Set().Include(c => c.Orders), + c => c.CustomerID == "ALFKI ?"); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_single_or_default_no_result(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_when_projection(bool async) { - using var context = CreateContext(); - var customer - = useString - ? context.Set() - .Include("Orders") - .SingleOrDefault(c => c.CustomerID == "ALFKI ?") - : context.Set() - .Include(c => c.Orders) - .SingleOrDefault(c => c.CustomerID == "ALFKI ?"); - - Assert.Null(customer); + return AssertQuery( + async, + ss => ss.Set().Include("Orders").Select(c => c.CustomerID)); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_when_projection(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_with_filter(bool async) { - using var context = CreateContext(); - var productIds - = useString - ? context.Set() - .Include(c => c.Orders) - .Select(c => c.CustomerID) - .ToList() - : context.Set() - .Include("Orders") - .Select(c => c.CustomerID) - .ToList(); - - Assert.Equal(91, productIds.Count); - Assert.Empty(context.ChangeTracker.Entries()); + return AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders).Where(c => c.CustomerID == "ALFKI"), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 7); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_filter(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_with_filter_reordered(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Include("Orders") - .Where(c => c.CustomerID == "ALFKI") - .ToList() - : context.Set() - .Include(c => c.Orders) - .Where(c => c.CustomerID == "ALFKI") - .ToList(); + return AssertQuery( + async, + ss => ss.Set().Where(c => c.CustomerID == "ALFKI").Include(c => c.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 7); + } - Assert.Single(customers); - Assert.Equal(6, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_duplicate_collection(bool async) + { + return AssertQuery( + async, + ss => from c1 in ss.Set().Include(c => c.Orders).OrderBy(c => c.CustomerID).Take(2) + from c2 in ss.Set().Include(c => c.Orders).OrderBy(c => c.CustomerID).Skip(2).Take(2) + select new { c1, c2 }, + elementSorter: e => (e.c1.CustomerID, e.c2.CustomerID), + elementAsserter: (e, a) => + { + AssertInclude(e.c1, a.c1, new ExpectedInclude(c => c.Orders)); + AssertInclude(e.c2, a.c2, new ExpectedInclude(c => c.Orders)); + }, + entryCount: 34); + } - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_duplicate_collection_result_operator(bool async) + { + return AssertQuery( + async, + ss => (from c1 in ss.Set().Include(c => c.Orders).OrderBy(c => c.CustomerID).Take(2) + from c2 in ss.Set().Include(c => c.Orders).OrderBy(c => c.CustomerID).Skip(2).Take(2) + select new { c1, c2 }).Take(1), + elementSorter: e => (e.c1.CustomerID, e.c2.CustomerID), + elementAsserter: (e, a) => + { + AssertInclude(e.c1, a.c1, new ExpectedInclude(c => c.Orders)); + AssertInclude(e.c2, a.c2, new ExpectedInclude(c => c.Orders)); + }, + entryCount: 15); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_filter_reordered(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_duplicate_collection_result_operator2(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Where(c => c.CustomerID == "ALFKI") - .Include("Orders") - .ToList() - : context.Set() - .Where(c => c.CustomerID == "ALFKI") - .Include(c => c.Orders) - .ToList(); - - Assert.Single(customers); - Assert.Equal(6, customers.SelectMany(c => c.Orders).Count()); - Assert.True(customers.SelectMany(c => c.Orders).All(o => o.Customer != null)); - Assert.Equal(1 + 6, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } - } - - [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_duplicate_collection(bool useString) - { - using var context = CreateContext(); - var customers - = useString - ? (from c1 in context.Set() - .Include("Orders") - .OrderBy(c => c.CustomerID) - .Take(2) - from c2 in context.Set() - .Include("Orders") - .OrderBy(c => c.CustomerID) - .Skip(2) - .Take(2) - select new { c1, c2 }) - .ToList() - : (from c1 in context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .Take(2) - from c2 in context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .Skip(2) - .Take(2) - select new { c1, c2 }) - .ToList(); - - Assert.Equal(4, customers.Count); - Assert.Equal(20, customers.SelectMany(c => c.c1.Orders).Count()); - Assert.True(customers.SelectMany(c => c.c1.Orders).All(o => o.Customer != null)); - Assert.Equal(40, customers.SelectMany(c => c.c2.Orders).Count()); - Assert.True(customers.SelectMany(c => c.c2.Orders).All(o => o.Customer != null)); - Assert.Equal(34, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers.Select(e => e.c1)) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } - - foreach (var customer in customers.Select(e => e.c2)) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } - } - - [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_duplicate_collection_result_operator(bool useString) - { - using var context = CreateContext(); - var customers - = useString - ? (from c1 in context.Set() - .Include("Orders") - .OrderBy(c => c.CustomerID) - .Take(2) - from c2 in context.Set() - .Include("Orders") - .OrderBy(c => c.CustomerID) - .Skip(2) - .Take(2) - select new { c1, c2 }) - .Take(1) - .ToList() - : (from c1 in context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .Take(2) - from c2 in context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .Skip(2) - .Take(2) - select new { c1, c2 }) - .Take(1) - .ToList(); - - Assert.Single(customers); - Assert.Equal(6, customers.SelectMany(c => c.c1.Orders).Count()); - Assert.True(customers.SelectMany(c => c.c1.Orders).All(o => o.Customer != null)); - Assert.Equal(7, customers.SelectMany(c => c.c2.Orders).Count()); - Assert.True(customers.SelectMany(c => c.c2.Orders).All(o => o.Customer != null)); - Assert.Equal(15, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers.Select(e => e.c1)) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } - - foreach (var customer in customers.Select(e => e.c2)) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } - } - - [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_duplicate_collection_result_operator2(bool useString) - { - using var context = CreateContext(); - var customers - = useString - ? (from c1 in context.Set() - .Include("Orders") - .OrderBy(c => c.CustomerID) - .Take(2) - from c2 in context.Set() - .OrderBy(c => c.CustomerID) - .Skip(2) - .Take(2) - select new { c1, c2 }) - .Take(1) - .ToList() - : (from c1 in context.Set() - .Include(c => c.Orders) - .OrderBy(c => c.CustomerID) - .Take(2) - from c2 in context.Set() - .OrderBy(c => c.CustomerID) - .Skip(2) - .Take(2) - select new { c1, c2 }) - .Take(1) - .ToList(); - - Assert.Single(customers); - Assert.Equal(6, customers.SelectMany(c => c.c1.Orders).Count()); - Assert.True(customers.SelectMany(c => c.c1.Orders).All(o => o.Customer != null)); - Assert.True(customers.All(c => c.c2.Orders == null)); - Assert.Equal(8, context.ChangeTracker.Entries().Count()); - - foreach (var customer in customers.Select(e => e.c1)) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } - - foreach (var customer in customers.Select(e => e.c2)) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: false, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => (from c1 in ss.Set().Include(c => c.Orders).OrderBy(c => c.CustomerID).Take(2) + from c2 in ss.Set().OrderBy(c => c.CustomerID).Skip(2).Take(2) + select new { c1, c2 }).Take(1), + elementSorter: e => (e.c1.CustomerID, e.c2.CustomerID), + elementAsserter: (e, a) => + { + AssertInclude(e.c1, a.c1, new ExpectedInclude(c => c.Orders)); + AssertEqual(e.c2, a.c2); + }, + entryCount: 8); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_duplicate_reference(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_duplicate_reference(bool async) { - using var context = CreateContext(); - var orders - = useString - ? (from o1 in context.Set() - .Include("Customer") - .OrderBy(o => o.CustomerID) - .ThenBy(o => o.OrderID) - .Take(2) - from o2 in context.Set() - .Include("Customer") - .OrderBy(o => o.CustomerID) - .ThenBy(o => o.OrderID) - .Skip(2) - .Take(2) - select new { o1, o2 }) - .ToList() - : (from o1 in context.Set() - .Include(o => o.Customer) - .OrderBy(o => o.CustomerID) - .ThenBy(o => o.OrderID) - .Take(2) - from o2 in context.Set() - .Include(o => o.Customer) - .OrderBy(o => o.CustomerID) - .ThenBy(o => o.OrderID) - .Skip(2) - .Take(2) - select new { o1, o2 }) - .ToList(); - - Assert.Equal(4, orders.Count); - Assert.True(orders.All(o => o.o1.Customer != null)); - Assert.True(orders.All(o => o.o2.Customer != null)); - Assert.Single(orders.Select(o => o.o1.Customer).Distinct()); - Assert.Single(orders.Select(o => o.o2.Customer).Distinct()); - Assert.Equal(5, context.ChangeTracker.Entries().Count()); - - foreach (var order in orders.Select(e => e.o1)) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } - - foreach (var order in orders.Select(e => e.o2)) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => from o1 in ss.Set().Include(o => o.Customer).OrderBy(o => o.CustomerID).ThenBy(o => o.OrderID).Take(2) + from o2 in ss.Set().Include(o => o.Customer).OrderBy(o => o.CustomerID).ThenBy(o => o.OrderID).Skip(2).Take(2) + select new { o1, o2 }, + elementSorter: e => (e.o1.OrderID, e.o2.OrderID), + elementAsserter: (e, a) => + { + AssertInclude(e.o1, a.o1, new ExpectedInclude(c => c.Customer)); + AssertInclude(e.o2, a.o2, new ExpectedInclude(c => c.Customer)); + }, + entryCount: 5); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_duplicate_reference2(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_duplicate_reference2(bool async) { - using var context = CreateContext(); - var orders - = useString - ? (from o1 in context.Set() - .Include("Customer") - .OrderBy(o => o.OrderID) - .Take(2) - from o2 in context.Set() - .OrderBy(o => o.OrderID) - .Skip(2) - .Take(2) - select new { o1, o2 }) - .ToList() - : (from o1 in context.Set() - .Include(o => o.Customer) - .OrderBy(o => o.OrderID) - .Take(2) - from o2 in context.Set() - .OrderBy(o => o.OrderID) - .Skip(2) - .Take(2) - select new { o1, o2 }) - .ToList(); - - Assert.Equal(4, orders.Count); - Assert.True(orders.All(o => o.o1.Customer != null)); - Assert.True(orders.All(o => o.o2.Customer == null)); - Assert.Equal(2, orders.Select(o => o.o1.Customer).Distinct().Count()); - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - - foreach (var order in orders.Select(e => e.o1)) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } - - foreach (var order in orders.Select(e => e.o2)) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => from o1 in ss.Set().Include(o => o.Customer).OrderBy(o => o.OrderID).Take(2) + from o2 in ss.Set().OrderBy(o => o.OrderID).Skip(2).Take(2) + select new { o1, o2 }, + elementSorter: e => (e.o1.OrderID, e.o2.OrderID), + elementAsserter: (e, a) => + { + AssertInclude(e.o1, a.o1, new ExpectedInclude(c => c.Customer)); + AssertEqual(e.o2, a.o2); + }, + entryCount: 6); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_duplicate_reference3(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_duplicate_reference3(bool async) { - using var context = CreateContext(); - var orders - = useString - ? (from o1 in context.Set() - .OrderBy(o => o.OrderID) - .Take(2) - from o2 in context.Set() - .OrderBy(o => o.OrderID) - .Include("Customer") - .Skip(2) - .Take(2) - select new { o1, o2 }) - .ToList() - : (from o1 in context.Set() - .OrderBy(o => o.OrderID) - .Take(2) - from o2 in context.Set() - .OrderBy(o => o.OrderID) - .Include(o => o.Customer) - .Skip(2) - .Take(2) - select new { o1, o2 }) - .ToList(); - - Assert.Equal(4, orders.Count); - Assert.True(orders.All(o => o.o1.Customer == null)); - Assert.True(orders.All(o => o.o2.Customer != null)); - Assert.Equal(2, orders.Select(o => o.o2.Customer).Distinct().Count()); - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - - foreach (var order in orders.Select(e => e.o1)) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } - - foreach (var order in orders.Select(e => e.o2)) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => from o1 in ss.Set().OrderBy(o => o.OrderID).Take(2) + from o2 in ss.Set().OrderBy(o => o.OrderID).Include(o => o.Customer).Skip(2).Take(2) + select new { o1, o2 }, + elementSorter: e => (e.o1.OrderID, e.o2.OrderID), + elementAsserter: (e, a) => + { + AssertEqual(e.o1, a.o1); + AssertInclude(e.o2, a.o2, new ExpectedInclude(c => c.Customer)); + }, + entryCount: 6); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_client_filter(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_collection_with_client_filter(bool async) { - using var context = CreateContext(); Assert.Contains( CoreStrings.TranslationFailedWithDetails( "", CoreStrings.QueryUnableToTranslateMember(nameof(Customer.IsLondon), nameof(Customer))).Substring(21), - Assert.Throws( - () => useString - ? context.Set() - .Include("Orders") - .Where(c => c.IsLondon) - .ToList() - : context.Set() - .Include(c => c.Orders) - .Where(c => c.IsLondon) - .ToList()).Message.Replace("\r", "").Replace("\n", "")); + (await Assert.ThrowsAsync( + () => AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders).Where(c => c.IsLondon)))) + .Message.Replace("\r", "").Replace("\n", "")); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multi_level_reference_and_collection_predicate(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multi_level_reference_and_collection_predicate(bool async) { - using var context = CreateContext(); - var order - = useString - ? context.Set() - .Include("Customer.Orders") - .Single(o => o.OrderID == 10248) - : context.Set() - .Include(o => o.Customer.Orders) - .Single(o => o.OrderID == 10248); - - Assert.NotNull(order.Customer); - Assert.True(order.Customer.Orders.All(o => o != null)); - - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: true); + return AssertSingle( + async, + ss => ss.Set().Include(o => o.Customer.Orders), + o => o.OrderID == 10248, + asserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(o => o.Customer), + new ExpectedInclude(c => c.Orders, "Customer")), + entryCount: 6); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multi_level_collection_and_then_include_reference_predicate(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multi_level_collection_and_then_include_reference_predicate(bool async) { - using var context = CreateContext(); - var order - = useString - ? context.Set() - .Include("OrderDetails.Product") - .Single(o => o.OrderID == 10248) - : context.Set() - .Include(o => o.OrderDetails).ThenInclude(od => od.Product) - .Single(o => o.OrderID == 10248); - - Assert.NotNull(order.OrderDetails); - Assert.True(order.OrderDetails.Count > 0); - Assert.True(order.OrderDetails.All(od => od.Product != null)); - - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: true, - customerLoaded: false, - ordersLoaded: false); + return AssertSingle( + async, + ss => ss.Set().Include(o => o.OrderDetails).ThenInclude(od => od.Product), + o => o.OrderID == 10248, + asserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(o => o.OrderDetails), + new ExpectedInclude(od => od.Product, "OrderDetails")), + entryCount: 7); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multiple_references(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multiple_references(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order") - .Include("Product") - .ToList() - : context.Set() - .Include(o => o.Order) - .Include(o => o.Product) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(o => o.Order != null)); - Assert.True(orderDetails.All(o => o.Product != null)); - Assert.Equal(830, orderDetails.Select(o => o.Order).Distinct().Count()); - Assert.True(orderDetails.Select(o => o.Product).Distinct().Any()); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: true, - customerLoaded: false, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Order).Include(o => o.Product), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(od => od.Product)), + entryCount: 3062); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multiple_references_and_collection_multi_level(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multiple_references_and_collection_multi_level(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order.Customer.Orders") - .Include("Product") - .ToList() - : context.Set() - .Include(od => od.Order.Customer.Orders) - .Include(od => od.Product) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: true, - customerLoaded: true, - ordersLoaded: true); - } + return AssertQuery( + async, + ss => ss.Set().Include(od => od.Order.Customer.Orders).Include(od => od.Product), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(c => c.Orders, "Order.Customer"), + new ExpectedInclude(od => od.Product)), + entryCount: 3151); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multiple_references_and_collection_multi_level_reverse(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multiple_references_and_collection_multi_level_reverse(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Product") - .Include("Order.Customer.Orders") - .ToList() - : context.Set() - .Include(od => od.Product) - .Include(od => od.Order.Customer.Orders) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: true, - customerLoaded: true, - ordersLoaded: true); - } + return AssertQuery( + async, + ss => ss.Set().Include(od => od.Product).Include(od => od.Order.Customer.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(c => c.Orders, "Order.Customer"), + new ExpectedInclude(od => od.Product)), + entryCount: 3151); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multiple_references_multi_level(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multiple_references_multi_level(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order.Customer") - .Include("Product") - .ToList() - : context.Set() - .Include(o => o.Order.Customer) - .Include(o => o.Product) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: true, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Order.Customer).Include(o => o.Product), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(od => od.Product)), + entryCount: 3151); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multiple_references_multi_level_reverse(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multiple_references_multi_level_reverse(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Product") - .Include("Order.Customer") - .ToList() - : context.Set() - .Include(o => o.Product) - .Include(o => o.Order.Customer) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: true, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Product).Include(o => o.Order.Customer), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(od => od.Product)), + entryCount: 3151); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Set() - .Include("Customer") - .ToList() - : context.Set() - .Include(o => o.Customer) - .ToList(); - - Assert.Equal(830, orders.Count); - Assert.True(orders.All(o => o.Customer != null)); - Assert.Equal(89, orders.Select(o => o.Customer).Distinct().Count()); - Assert.Equal(830 + 89, context.ChangeTracker.Entries().Count()); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } - } - - [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_alias_generation(bool useString) - { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order") - .ToList() - : context.Set() - .Include(o => o.Order) - .ToList(); - - Assert.True(orderDetails.Count > 0); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Customer), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(o => o.Customer)), + entryCount: 919); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_and_collection(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_alias_generation(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Set() - .Include("Customer") - .Include("OrderDetails") - .ToList() - : context.Set() - .Include(o => o.Customer) - .Include(o => o.OrderDetails) - .ToList(); - - Assert.Equal(830, orders.Count); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Order), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(od => od.Order)), + entryCount: 2985); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_force_alias_uniquefication(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_and_collection(bool async) { - using var context = CreateContext(); - var result - = useString - ? (from o in context.Set().Include("OrderDetails") - where o.CustomerID == "ALFKI" - select o) - .ToList() - : (from o in context.Set().Include(o => o.OrderDetails) - where o.CustomerID == "ALFKI" - select o) - .ToList(); - - Assert.Equal(6, result.Count); - Assert.True(result.SelectMany(r => r.OrderDetails).All(od => od.Order != null)); - - foreach (var order in result) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Customer).Include(o => o.OrderDetails), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(o => o.Customer), + new ExpectedInclude(o => o.OrderDetails)), + entryCount: 3074); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_as_no_tracking(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_force_alias_uniquefication(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Set() - .Include("Customer") - .AsNoTracking() - .ToList() - : context.Set() - .Include(o => o.Customer) - .AsNoTracking() - .ToList(); - - Assert.Equal(830, orders.Count); - Assert.True(orders.All(o => o.Customer != null)); - Assert.Empty(context.ChangeTracker.Entries()); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => from o in ss.Set().Include(o => o.OrderDetails) + where o.CustomerID == "ALFKI" + select o, + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(o => o.OrderDetails)), + entryCount: 18); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_dependent_already_tracked(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_reference_dependent_already_tracked(bool async) { using var context = CreateContext(); - var orders1 - = context.Set() - .Where(o => o.CustomerID == "ALFKI") - .ToList(); - - Assert.Equal(6, context.ChangeTracker.Entries().Count()); - - var orders2 - = useString - ? context.Set() - .Include("Customer") - .ToList() - : context.Set() - .Include(o => o.Customer) - .ToList(); + var customer = context.Set().Single(o => o.CustomerID == "ALFKI"); + Assert.Single(context.ChangeTracker.Entries()); - Assert.True(orders1.All(o1 => orders2.Contains(o1, LegacyReferenceEqualityComparer.Instance))); - Assert.True(orders2.All(o => o.Customer != null)); - Assert.Equal(830 + 89, context.ChangeTracker.Entries().Count()); + var orders + = async + ? await context.Set().Include(o => o.Customer).Where(o => o.CustomerID == "ALFKI").ToListAsync() + : context.Set().Include(o => o.Customer).Where(o => o.CustomerID == "ALFKI").ToList(); - foreach (var order in orders2) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + Assert.True(orders.All(o => ReferenceEquals(o.Customer, customer))); + Assert.Equal(7, context.ChangeTracker.Entries().Count()); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_single_or_default_when_no_result(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_single_or_default_when_no_result(bool async) { - using var context = CreateContext(); - var order - = useString - ? context.Set() - .Include("Customer") - .SingleOrDefault(o => o.OrderID == -1) - : context.Set() - .Include(o => o.Customer) - .SingleOrDefault(o => o.OrderID == -1); - - Assert.Null(order); + return AssertSingleOrDefault( + async, + ss => ss.Set().Include(o => o.Customer), + o => o.OrderID == -1, + asserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(o => o.Customer))); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_when_projection(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_when_projection(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Set() - .Include("Customer") - .Select(o => o.CustomerID) - .ToList() - : context.Set() - .Include(o => o.Customer) - .Select(o => o.CustomerID) - .ToList(); - - Assert.Equal(830, orders.Count); - Assert.Empty(context.ChangeTracker.Entries()); + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Customer).Select(o => o.CustomerID)); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_when_entity_in_projection(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_when_entity_in_projection(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Set() - .Include("Customer") - .Select( - o => new { o, o.CustomerID }) - .ToList() - : context.Set() - .Include(o => o.Customer) - .Select( - o => new { o, o.CustomerID }) - .ToList(); - - Assert.Equal(830, orders.Count); - Assert.Equal(919, context.ChangeTracker.Entries().Count()); - - foreach (var order in orders.Select(e => e.o)) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Customer).Select(o => new { o, o.CustomerID }), + elementSorter: e => e.o.OrderID, + elementAsserter: (e, a) => + { + AssertInclude(e.o, a.o, new ExpectedInclude(o => o.Customer)); + AssertEqual(e.CustomerID, a.CustomerID); + }, + entryCount: 919); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_with_filter(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_with_filter(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Set() - .Include("Customer") - .Where(o => o.CustomerID == "ALFKI") - .ToList() - : context.Set() - .Include(o => o.Customer) - .Where(o => o.CustomerID == "ALFKI") - .ToList(); - - Assert.Equal(6, orders.Count); - Assert.True(orders.All(o => o.Customer != null)); - Assert.Single(orders.Select(o => o.Customer).Distinct()); - Assert.Equal(6 + 1, context.ChangeTracker.Entries().Count()); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Customer).Where(o => o.CustomerID == "ALFKI"), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(o => o.Customer)), + entryCount: 7); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_with_filter_reordered(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_with_filter_reordered(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Set() - .Where(o => o.CustomerID == "ALFKI") - .Include("Customer") - .ToList() - : context.Set() - .Where(o => o.CustomerID == "ALFKI") - .Include(o => o.Customer) - .ToList(); - - Assert.Equal(6, orders.Count); - Assert.True(orders.All(o => o.Customer != null)); - Assert.Single(orders.Select(o => o.Customer).Distinct()); - - Assert.Equal(6 + 1, context.ChangeTracker.Entries().Count()); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Where(o => o.CustomerID == "ALFKI").Include(o => o.Customer), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(o => o.Customer)), + entryCount: 7); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_references_and_collection_multi_level(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_references_and_collection_multi_level(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order.Customer.Orders") - .ToList() - : context.Set() - .Include(o => o.Order.Customer.Orders) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: false, - customerLoaded: true, - ordersLoaded: true); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Order.Customer.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(c => c.Orders, "Order.Customer")), + entryCount: 3074); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_then_include_collection(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_then_include_collection(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Include("Orders.OrderDetails") - .ToList() - : context.Set() - .Include(c => c.Orders).ThenInclude(o => o.OrderDetails) - .ToList(); - - Assert.Equal(91, customers.Count); - Assert.True(customers.All(c => c.Orders != null)); - Assert.True(customers.All(c => c.Orders.All(o => o.OrderDetails != null))); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: true, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders).ThenInclude(o => o.OrderDetails), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(c => c.Orders), + new ExpectedInclude(o => o.OrderDetails, "Orders")), + entryCount: 3076); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_then_include_collection_then_include_reference(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_then_include_collection_then_include_reference(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .Include("Orders.OrderDetails.Product") - .ToList() - : context.Set() - .Include(c => c.Orders).ThenInclude(o => o.OrderDetails).ThenInclude(od => od.Product) - .ToList(); - - Assert.Equal(91, customers.Count); - Assert.True(customers.All(c => c.Orders != null)); - Assert.True(customers.All(c => c.Orders.All(o => o.OrderDetails != null))); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: true, - productLoaded: true); - } + return AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders).ThenInclude(o => o.OrderDetails).ThenInclude(od => od.Product), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(c => c.Orders), + new ExpectedInclude(o => o.OrderDetails, "Orders"), + new ExpectedInclude(od => od.Product, "Orders.OrderDetails")), + entryCount: 3153); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_then_include_collection_predicate(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_then_include_collection_predicate(bool async) { - using var context = CreateContext(); - var customer - = useString - ? context.Set() - .Include("Orders.OrderDetails") - .SingleOrDefault(c => c.CustomerID == "ALFKI") - : context.Set() - .Include(c => c.Orders).ThenInclude(o => o.OrderDetails) - .SingleOrDefault(c => c.CustomerID == "ALFKI"); - - Assert.NotNull(customer); - Assert.Equal(6, customer.Orders.Count); - Assert.True(customer.Orders.SelectMany(o => o.OrderDetails).Count() >= 6); - - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: true, - productLoaded: false); + return AssertSingleOrDefault( + async, + ss => ss.Set().Include(c => c.Orders).ThenInclude(o => o.OrderDetails), + c => c.CustomerID == "ALFKI", + asserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(c => c.Orders), + new ExpectedInclude(o => o.OrderDetails, "Orders")), + entryCount: 19); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_references_and_collection_multi_level_predicate(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_references_and_collection_multi_level_predicate(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order.Customer.Orders") - .Where(od => od.OrderID == 10248) - .ToList() - : context.Set() - .Include(od => od.Order.Customer.Orders) - .Where(od => od.OrderID == 10248) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: false, - customerLoaded: true, - ordersLoaded: true); - } + return AssertQuery( + async, + ss => ss.Set().Include(od => od.Order.Customer.Orders).Where(od => od.OrderID == 10248), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(c => c.Orders, "Order.Customer")), + entryCount: 9); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_references_multi_level(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_references_multi_level(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order.Customer") - .ToList() - : context.Set() - .Include(o => o.Order.Customer) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(o => o.Order.Customer), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order")), + entryCount: 3074); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multi_level_reference_then_include_collection_predicate(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multi_level_reference_then_include_collection_predicate(bool async) { - using var context = CreateContext(); - var order - = useString - ? context.Set() - .Include("Customer.Orders") - .Single(o => o.OrderID == 10248) - : context.Set() - .Include(o => o.Customer).ThenInclude(c => c.Orders) - .Single(o => o.OrderID == 10248); - - Assert.NotNull(order.Customer); - Assert.True(order.Customer.Orders.All(o => o != null)); - - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: true); + return AssertSingle( + async, + ss => ss.Set().Include(o => o.Customer).ThenInclude(c => c.Orders), + o => o.OrderID == 10248, + asserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(o => o.Customer), + new ExpectedInclude(c => c.Orders, "Customer")), + entryCount: 6); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multiple_references_then_include_collection_multi_level(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multiple_references_then_include_collection_multi_level(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order.Customer.Orders") - .Include("Product") - .ToList() - : context.Set() + return AssertQuery( + async, + ss => ss.Set() .Include(od => od.Order).ThenInclude(o => o.Customer).ThenInclude(c => c.Orders) - .Include(od => od.Product) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: true, - customerLoaded: true, - ordersLoaded: true); - } + .Include(od => od.Product), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(c => c.Orders, "Order.Customer"), + new ExpectedInclude(od => od.Product)), + entryCount: 3151); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multiple_references_then_include_collection_multi_level_reverse(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multiple_references_then_include_collection_multi_level_reverse(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include(nameof(OrderDetail.Product)) - .Include(nameof(OrderDetail.Order) + "." + nameof(Order.Customer) + "." + nameof(Customer.Orders)) - .ToList() - : context.Set() + return AssertQuery( + async, + ss => ss.Set() .Include(od => od.Product) - .Include(od => od.Order).ThenInclude(o => o.Customer).ThenInclude(c => c.Orders) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: true, - customerLoaded: true, - ordersLoaded: true); - } + .Include(od => od.Order).ThenInclude(o => o.Customer).ThenInclude(c => c.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(c => c.Orders, "Order.Customer"), + new ExpectedInclude(od => od.Product)), + entryCount: 3151); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multiple_references_then_include_multi_level(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multiple_references_then_include_multi_level(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order.Customer") - .Include("Product") - .ToList() - : context.Set() + return AssertQuery( + async, + ss => ss.Set() .Include(od => od.Order).ThenInclude(o => o.Customer) - .Include(od => od.Product) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: true, - customerLoaded: true, - ordersLoaded: false); - } + .Include(od => od.Product), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(od => od.Product)), + entryCount: 3151); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_multiple_references_then_include_multi_level_reverse(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_multiple_references_then_include_multi_level_reverse(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Product") - .Include("Order.Customer") - .ToList() - : context.Set() + return AssertQuery( + async, + ss => ss.Set() .Include(od => od.Product) - .Include(od => od.Order).ThenInclude(o => o.Customer) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: true, - customerLoaded: true, - ordersLoaded: false); - } + .Include(od => od.Order).ThenInclude(o => o.Customer), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(od => od.Product)), + entryCount: 3151); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_references_then_include_collection_multi_level(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_references_then_include_collection_multi_level(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order.Customer.Orders") - .ToList() - : context.Set() - .Include(od => od.Order).ThenInclude(o => o.Customer).ThenInclude(c => c.Orders) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: false, - customerLoaded: true, - ordersLoaded: true); - } + return AssertQuery( + async, + ss => ss.Set() + .Include(od => od.Order).ThenInclude(o => o.Customer).ThenInclude(c => c.Orders), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(c => c.Orders, "Order.Customer")), + entryCount: 3074); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_references_then_include_collection_multi_level_predicate(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_references_then_include_collection_multi_level_predicate(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order.Customer.Orders") - .Where(od => od.OrderID == 10248) - .ToList() - : context.Set() + return AssertQuery( + async, + ss => ss.Set() .Include(od => od.Order).ThenInclude(o => o.Customer).ThenInclude(c => c.Orders) - .Where(od => od.OrderID == 10248) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - Assert.True(orderDetails.All(od => od.Order.Customer.Orders != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: false, - customerLoaded: true, - ordersLoaded: true); - } + .Where(od => od.OrderID == 10248), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order"), + new ExpectedInclude(c => c.Orders, "Order.Customer")), + entryCount: 9); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_references_then_include_multi_level(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_references_then_include_multi_level(bool async) { - using var context = CreateContext(); - var orderDetails - = useString - ? context.Set() - .Include("Order.Customer") - .ToList() - : context.Set() - .Include(od => od.Order).ThenInclude(o => o.Customer) - .ToList(); - - Assert.True(orderDetails.Count > 0); - Assert.True(orderDetails.All(od => od.Order.Customer != null)); - - foreach (var orderDetail in orderDetails) - { - CheckIsLoaded( - context, - orderDetail, - orderLoaded: true, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set() + .Include(od => od.Order).ThenInclude(o => o.Customer), + elementAsserter: (e, a) => AssertInclude(e, a, + new ExpectedInclude(od => od.Order), + new ExpectedInclude(o => o.Customer, "Order")), + entryCount: 3074); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_with_complex_projection(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_with_complex_projection(bool async) { - using var context = CreateContext(); - var query = useString - ? from o in context.Orders.Include("Customer") - select new { CustomerId = new { Id = o.Customer.CustomerID } } - : from o in context.Orders.Include(o => o.Customer) - select new { CustomerId = new { Id = o.Customer.CustomerID } }; - - var results = query.ToList(); - - Assert.Equal(830, results.Count); + return AssertQuery( + async, + ss => from o in ss.Set().Include(o => o.Customer) + select new { CustomerId = new { Id = o.Customer.CustomerID } }); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_with_complex_projection_does_not_change_ordering_of_projection(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_with_complex_projection_does_not_change_ordering_of_projection(bool async) { - using var context = CreateContext(); - var q = useString - ? from c in context.Customers.Include(nameof(Customer.Orders)) - .Where(c => c.ContactTitle == "Owner") - .OrderBy(c => c.CustomerID) - select new { Id = c.CustomerID, TotalOrders = c.Orders.Count } - : from c in context.Customers.Include(c => c.Orders) - .Where(c => c.ContactTitle == "Owner") - .OrderBy(c => c.CustomerID) - select new { Id = c.CustomerID, TotalOrders = c.Orders.Count }; - - var result = q.Where(e => e.TotalOrders > 2).ToList(); - - Assert.Equal(15, result.Count); + return AssertQuery( + async, + ss => from c in ss.Set().Include(c => c.Orders).Where(c => c.ContactTitle == "Owner").OrderBy(c => c.CustomerID) + select new { Id = c.CustomerID, TotalOrders = c.Orders.Count }); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_with_take(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_with_take(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Set() - .OrderByDescending(c => c.City) - .Include("Orders") - .Take(10) - .ToList() - : context.Set() - .OrderByDescending(c => c.City) - .Include(c => c.Orders) - .Take(10) - .ToList(); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().OrderByDescending(c => c.ContactName).Include(c => c.Orders).Take(10), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 75); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_with_skip(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_with_skip(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Customers - .Include("Orders") - .OrderBy(c => c.ContactName) - .Skip(80) - .ToList() - : context.Customers - .Include(c => c.Orders) - .OrderBy(c => c.ContactName) - .Skip(80) - .ToList(); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders).OrderBy(c => c.ContactName).Skip(80), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 106); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_multiple_conditional_order_by(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_with_multiple_conditional_order_by(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Orders - .Include("OrderDetails") - .OrderBy(o => o.OrderID > 0) - .ThenBy(o => o.Customer != null ? o.Customer.City : string.Empty) - .Take(5) - .ToList() - : context.Orders + return AssertQuery( + async, + ss => ss.Set() .Include(c => c.OrderDetails) .OrderBy(o => o.OrderID > 0) .ThenBy(o => o.Customer != null ? o.Customer.City : string.Empty) - .Take(5) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + .Take(5), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(o => o.OrderDetails)), + entryCount: 14); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_with_conditional_order_by(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_with_conditional_order_by(bool async) { - int customersWithPrefix; - using (var context = CreateContext()) - { - customersWithPrefix = context.Customers.Count(c => c.CustomerID.StartsWith("S")); - } - - ClearLog(); - - using (var context = CreateContext()) - { - var customers - = useString - ? context.Customers - .OrderBy(c => c.CustomerID.StartsWith("S") ? 1 : 2) - .Include(c => c.Orders) - .ToList() - : context.Customers - .OrderBy(c => c.CustomerID.StartsWith("S") ? 1 : 2) - .Include("Orders") - .ToList(); - - Assert.True(customers.Take(customersWithPrefix).All(c => c.CustomerID.StartsWith("S"))); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } - } + return AssertQuery( + async, + ss => ss.Set().Include(c => c.Orders).OrderBy(c => c.CustomerID.StartsWith("S") ? 1 : 2), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + assertOrder: true, + entryCount: 921); } [ConditionalTheory(Skip = "issue #15312")] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_specified_on_non_entity_not_supported(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual async Task Include_specified_on_non_entity_not_supported(bool async) { - using var context = CreateContext(); Assert.Equal( CoreStrings.IncludeNotSpecifiedDirectlyOnEntityType(@"Include(""Item1.Orders"")", "Item1"), - Assert.Throws( - () => useString - ? context.Customers - .Select(c => new Tuple(c, 5)) - .Include(t => t.Item1.Orders) - .ToList() - : context.Customers - .Select(c => new Tuple(c, 5)) - .Include("Item1.Orders") - .ToList()).Message); + (await Assert.ThrowsAsync( + () => AssertQuery( + async, + ss => ss.Set().Select(c => new Tuple(c, 5)).Include(t => t.Item1.Orders)))).Message); } [ConditionalTheory(Skip = "Issue #12088")] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_GroupBy_Select(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_GroupBy_Select(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Orders - .Where(o => o.OrderID == 10248) - .Include("OrderDetails") - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList() - : context.Orders + return AssertQuery( + async, + ss => ss.Set() .Where(o => o.OrderID == 10248) .Include(o => o.OrderDetails) .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault())); } [ConditionalTheory(Skip = "Issue #12088")] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_GroupBy_Select(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_GroupBy_Select(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Orders - .Where(o => o.OrderID == 10248) - .Include("Customer") - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList() - : context.Orders + return AssertQuery( + async, + ss => ss.Set() .Where(o => o.OrderID == 10248) .Include(o => o.Customer) .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault())); } [ConditionalTheory(Skip = "Issue #12088")] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_Join_GroupBy_Select(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_Join_GroupBy_Select(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Orders - .Where(o => o.OrderID == 10248) - .Include("OrderDetails") - .Join( - context.OrderDetails, - o => o.OrderID, - od => od.OrderID, - (o, od) => o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList() - : context.Orders + return AssertQuery( + async, + ss => ss.Set() .Where(o => o.OrderID == 10248) .Include(o => o.OrderDetails) .Join( - context.OrderDetails, + ss.Set(), o => o.OrderID, od => od.OrderID, (o, od) => o) .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault())); } [ConditionalTheory(Skip = "Issue #12088")] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_Join_GroupBy_Select(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_Join_GroupBy_Select(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Orders - .Where(o => o.OrderID == 10248) - .Include("Customer") - .Join( - context.OrderDetails, - o => o.OrderID, - od => od.OrderID, - (o, od) => o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList() - : context.Orders + return AssertQuery( + async, + ss => ss.Set() .Where(o => o.OrderID == 10248) .Include(o => o.Customer) .Join( - context.OrderDetails, + ss.Set(), o => o.OrderID, od => od.OrderID, (o, od) => o) .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault())); } [ConditionalTheory(Skip = "Issue #12088")] - [InlineData(false)] - [InlineData(true)] - public virtual void Join_Include_collection_GroupBy_Select(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Join_Include_collection_GroupBy_Select(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.OrderDetails - .Where(od => od.OrderID == 10248) - .Join( - context.Orders.Include("OrderDetails"), - od => od.OrderID, - o => o.OrderID, - (od, o) => o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList() - : context.OrderDetails + return AssertQuery( + async, + ss => ss.Set() .Where(od => od.OrderID == 10248) .Join( - context.Orders.Include(o => o.OrderDetails), + ss.Set().Include(o => o.OrderDetails), od => od.OrderID, o => o.OrderID, (od, o) => o) .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault())); } [ConditionalTheory(Skip = "Issue #12088")] - [InlineData(false)] - [InlineData(true)] - public virtual void Join_Include_reference_GroupBy_Select(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Join_Include_reference_GroupBy_Select(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.OrderDetails + return AssertQuery( + async, + ss => ss.Set() .Join( - context.Orders.Include("Customer"), + ss.Set().Include(o => o.Customer), od => od.OrderID, o => o.OrderID, (od, o) => o) .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList() - : context.OrderDetails - .Join( - context.Orders.Include(o => o.Customer), - od => od.OrderID, - o => o.OrderID, - (od, o) => o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault())); } [ConditionalTheory(Skip = "Issue #12088")] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_SelectMany_GroupBy_Select(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_SelectMany_GroupBy_Select(bool async) { - using var context = CreateContext(); - var orders - = useString - ? (from o in context.Orders.Include("OrderDetails").Where(o => o.OrderID == 10248) - from od in context.OrderDetails - select o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList() - : (from o in context.Orders.Include(o => o.OrderDetails).Where(o => o.OrderID == 10248) - from od in context.OrderDetails + return AssertQuery( + async, + ss => (from o in ss.Set().Include(o => o.OrderDetails).Where(o => o.OrderID == 10248) + from od in ss.Set() select o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + .GroupBy(e => e.OrderID) + .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault())); } [ConditionalTheory(Skip = "Issue #12088")] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_SelectMany_GroupBy_Select(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_SelectMany_GroupBy_Select(bool async) { - using var context = CreateContext(); - var orders - = useString - ? (from o in context.Orders.Include("Customer").Where(o => o.OrderID == 10248) - from od in context.OrderDetails + return AssertQuery( + async, + ss => (from o in ss.Set().Include(o => o.Customer).Where(o => o.OrderID == 10248) + from od in ss.Set() select o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList() - : (from o in context.Orders.Include(o => o.Customer).Where(o => o.OrderID == 10248) - from od in context.OrderDetails - select o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + .GroupBy(e => e.OrderID) + .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault())); } [ConditionalTheory(Skip = "Issue #12088")] - [InlineData(false)] - [InlineData(true)] - public virtual void SelectMany_Include_collection_GroupBy_Select(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task SelectMany_Include_collection_GroupBy_Select(bool async) { - using var context = CreateContext(); - var orders - = useString - ? (from od in context.OrderDetails.Where(od => od.OrderID == 10248) - from o in context.Orders.Include("OrderDetails") - select o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList() - : (from od in context.OrderDetails.Where(od => od.OrderID == 10248) - from o in context.Orders.Include(o => o.OrderDetails) + return AssertQuery( + async, + ss => (from od in ss.Set().Where(od => od.OrderID == 10248) + from o in ss.Set().Include(o => o.OrderDetails) select o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + .GroupBy(e => e.OrderID) + .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault())); } [ConditionalTheory(Skip = "Issue #12088")] - [InlineData(false)] - [InlineData(true)] - public virtual void SelectMany_Include_reference_GroupBy_Select(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task SelectMany_Include_reference_GroupBy_Select(bool async) { - using var context = CreateContext(); - var orders - = useString - ? (from od in context.OrderDetails.Where(od => od.OrderID == 10248) - from o in context.Orders.Include("Customer") - select o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList() - : (from od in context.OrderDetails.Where(od => od.OrderID == 10248) - from o in context.Orders.Include(o => o.Customer) + return AssertQuery( + async, + ss => (from od in ss.Set().Where(od => od.OrderID == 10248) + from o in ss.Set().Include(o => o.Customer) select o) - .GroupBy(e => e.OrderID) - .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault()) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + .GroupBy(e => e.OrderID) + .Select(e => e.OrderBy(o => o.OrderID).FirstOrDefault())); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_reference_distinct_is_server_evaluated(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_reference_distinct_is_server_evaluated(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Orders - .Where(o => o.OrderID < 10250) - .Include("Customer") - .Distinct() - .ToList() - : context.Orders - .Where(o => o.OrderID < 10250) - .Include(o => o.Customer) - .Distinct() - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: false, - productLoaded: false, - customerLoaded: true, - ordersLoaded: false); - } + return AssertQuery( + async, + ss => ss.Set().Where(o => o.OrderID < 10250).Include(o => o.Customer).Distinct(), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(o => o.Customer)), + entryCount: 4); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_distinct_is_server_evaluated(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_distinct_is_server_evaluated(bool async) { - using var context = CreateContext(); - var customers - = useString - ? context.Customers - .Where(c => c.CustomerID.StartsWith("A")) - .Include("Orders") - .Distinct() - .ToList() - : context.Customers + return AssertQuery( + async, + ss => ss.Set() .Where(c => c.CustomerID.StartsWith("A")) .Include(o => o.Orders) - .Distinct() - .ToList(); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + .Distinct(), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 34); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_OrderBy_object(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_OrderBy_object(bool async) { - using var context = CreateContext(); - var orders - = useString - ? context.Orders - .Where(o => o.OrderID < 10250) - .Include("OrderDetails") - .OrderBy(c => c.OrderID) - .ToList() - : context.Orders + return AssertQuery( + async, + ss => ss.Set() .Where(o => o.OrderID < 10250) .Include(o => o.OrderDetails) - .OrderBy(c => c.OrderID) - .ToList(); - - foreach (var order in orders) - { - CheckIsLoaded( - context, - order, - orderDetailsLoaded: true, - productLoaded: false, - customerLoaded: false, - ordersLoaded: false); - } + .OrderBy(c => c.OrderID), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(o => o.OrderDetails)), + assertOrder: true, + entryCount: 7); } [ConditionalTheory(Skip = "Issue#15713")] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_OrderBy_empty_list_contains(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_OrderBy_empty_list_contains(bool async) { - using var context = CreateContext(); var list = new List(); - var customers - = useString - ? context.Customers - .Include("Orders") - .Where(c => c.CustomerID.StartsWith("A")) - .OrderBy(c => list.Contains(c.CustomerID)) - .Skip(1) - .ToList() - : context.Customers + return AssertQuery( + async, + ss => ss.Set() .Include(c => c.Orders) .Where(c => c.CustomerID.StartsWith("A")) .OrderBy(c => list.Contains(c.CustomerID)) - .Skip(1) - .ToList(); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + .Skip(1), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders))); } [ConditionalTheory(Skip = "Issue#15713")] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_OrderBy_empty_list_does_not_contains(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_OrderBy_empty_list_does_not_contains(bool async) { - using var context = CreateContext(); var list = new List(); - var customers - = useString - ? context.Customers - .Include("Orders") - .Where(c => c.CustomerID.StartsWith("A")) - .OrderBy(c => !list.Contains(c.CustomerID)) - .Skip(1) - .ToList() - : context.Customers + return AssertQuery( + async, + ss => ss.Set() .Include(c => c.Orders) .Where(c => c.CustomerID.StartsWith("A")) .OrderBy(c => !list.Contains(c.CustomerID)) - .Skip(1) - .ToList(); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + .Skip(1), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders))); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_OrderBy_list_contains(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_OrderBy_list_contains(bool async) { - using var context = CreateContext(); var list = new List { "ALFKI" }; - var customers - = useString - ? context.Customers - .Include("Orders") - .Where(c => c.CustomerID.StartsWith("A")) - .OrderBy(c => list.Contains(c.CustomerID)) - .Skip(1) - .ToList() - : context.Customers + return AssertQuery( + async, + ss => ss.Set() .Include(c => c.Orders) .Where(c => c.CustomerID.StartsWith("A")) .OrderBy(c => list.Contains(c.CustomerID)) - .Skip(1) - .ToList(); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + .Skip(1), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 29); } [ConditionalTheory] - [InlineData(false)] - [InlineData(true)] - public virtual void Include_collection_OrderBy_list_does_not_contains(bool useString) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_collection_OrderBy_list_does_not_contains(bool async) { - using var context = CreateContext(); var list = new List { "ALFKI" }; - var customers - = useString - ? context.Customers - .Include("Orders") - .Where(c => c.CustomerID.StartsWith("A")) - .OrderBy(c => !list.Contains(c.CustomerID)) - .Skip(1) - .ToList() - : context.Customers + return AssertQuery( + async, + ss => ss.Set() .Include(c => c.Orders) .Where(c => c.CustomerID.StartsWith("A")) .OrderBy(c => !list.Contains(c.CustomerID)) - .Skip(1) - .ToList(); - - foreach (var customer in customers) - { - CheckIsLoaded( - context, - customer, - ordersLoaded: true, - orderDetailsLoaded: false, - productLoaded: false); - } + .Skip(1), + elementAsserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(c => c.Orders)), + entryCount: 27); } [ConditionalTheory] - [InlineData(false, false)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(true, true)] - public virtual async Task Include_empty_collection_sets_IsLoaded(bool useString, bool async) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_empty_reference_sets_IsLoaded(bool async) { - using var context = CreateContext(); - var customers = useString - ? context.Customers.Include(nameof(Customer.Orders)) - : context.Customers.Include(e => e.Orders); - - var customer = async - ? await customers.SingleAsync(e => e.CustomerID == "FISSA") - : customers.Single(e => e.CustomerID == "FISSA"); - - Assert.Empty(customer.Orders); - Assert.True(context.Entry(customer).Collection(e => e.Orders).IsLoaded); + return AssertFirst( + async, + ss => ss.Set().Include(e => e.Manager), + e => e.Manager == null, + asserter: (e, a) => AssertInclude(e, a, new ExpectedInclude(emp => emp.Manager)), + entryCount: 1); } [ConditionalTheory] - [InlineData(false, false)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(true, true)] - public virtual async Task Include_empty_reference_sets_IsLoaded(bool useString, bool async) + [MemberData(nameof(IsAsyncData))] + public virtual Task Include_is_not_ignored_when_projection_contains_client_method_and_complex_expression(bool async) { - using var context = CreateContext(); - var employees = useString - ? context.Employees.Include(nameof(Employee.Manager)) - : context.Employees.Include(e => e.Manager); - - var employee = async - ? await employees.FirstAsync(e => e.Manager == null) - : employees.First(e => e.Manager == null); - - Assert.Null(employee.Manager); - Assert.True(context.Entry(employee).Reference(e => e.Manager).IsLoaded); - } - - [ConditionalTheory] - [InlineData(false, false)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(true, true)] - public virtual async Task Include_is_not_ignored_when_projection_contains_client_method_and_complex_expression( - bool useString, bool async) - { - using var context = CreateContext(); - var query = from e in (useString - ? context.Employees.Include(nameof(Employee.Manager)) - : context.Employees.Include(e => e.Manager)) - where e.EmployeeID == 1 || e.EmployeeID == 2 - orderby e.EmployeeID - select e.Manager != null ? "Employee " + ClientMethod(e) : ""; - - var result = async - ? await query.ToListAsync() - : query.ToList(); - - Assert.Collection( - result, - e => Assert.Equal("Employee Nancy reports to Andrew", e), - e2 => Assert.Equal("", e2)); + return AssertQuery( + async, + ss => from e in ss.Set().Include(e => e.Manager) + where e.EmployeeID == 1 || e.EmployeeID == 2 + orderby e.EmployeeID + select e.Manager != null ? "Employee " + ClientMethod(e) : "", + entryCount: 2); } private static string ClientMethod(Employee e) - => e.FirstName + " reports to " + e.Manager.FirstName + e.Manager.LastName; + => e.FirstName + " reports to " + e.Manager.FirstName; // Issue#18672 [ConditionalTheory] - [InlineData(false, false)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(true, true)] - public virtual async Task Multi_level_includes_are_applied_with_skip(bool useString, bool async) - { - using var context = CreateContext(); - var query = (from c in (useString - ? context.Customers.Include("Orders.OrderDetails") - : context.Customers.Include(e => e.Orders).ThenInclude(e => e.OrderDetails)) - where c.CustomerID.StartsWith("A") - orderby c.CustomerID - select new { c.CustomerID, Orders = c.Orders.ToList() }) - .Skip(1); - - var result = async - ? await query.FirstAsync() - : query.First(); - - Assert.Equal("ANATR", result.CustomerID); - Assert.Equal(2, result.Orders.First().OrderDetails.Count); - } - - [ConditionalTheory] - [InlineData(false, false)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(true, true)] - public virtual async Task Multi_level_includes_are_applied_with_take(bool useString, bool async) - { - using var context = CreateContext(); - var query = (from c in (useString - ? context.Customers.Include("Orders.OrderDetails") - : context.Customers.Include(e => e.Orders).ThenInclude(e => e.OrderDetails)) - where c.CustomerID.StartsWith("A") - orderby c.CustomerID - select new { c.CustomerID, Orders = c.Orders.ToList() }) - .Take(1); - - var result = async - ? await query.FirstAsync() - : query.First(); - - Assert.Equal("ALFKI", result.CustomerID); - Assert.Equal(3, result.Orders.First().OrderDetails.Count); - } - - [ConditionalTheory] - [InlineData(false, false)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(true, true)] - public virtual async Task Multi_level_includes_are_applied_with_skip_take(bool useString, bool async) + [MemberData(nameof(IsAsyncData))] + public virtual Task Multi_level_includes_are_applied_with_skip(bool async) { - using var context = CreateContext(); - var query = (from c in (useString - ? context.Customers.Include("Orders.OrderDetails") - : context.Customers.Include(e => e.Orders).ThenInclude(e => e.OrderDetails)) - where c.CustomerID.StartsWith("A") - orderby c.CustomerID - select new { c.CustomerID, Orders = c.Orders.ToList() }) - .Skip(1) - .Take(1); - - var result = async - ? await query.FirstAsync() - : query.First(); - - Assert.Equal("ANATR", result.CustomerID); - Assert.Equal(2, result.Orders.First().OrderDetails.Count); - } - - [ConditionalTheory] - [InlineData(false, false)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(true, true)] - public virtual async Task NoTracking_Include_with_cycles_throws(bool useString, bool async) - { - using var context = CreateContext(); - var query = (from o in (useString - ? context.Orders.Include("Customer.Orders") - : context.Orders.Include(o => o.Customer.Orders)) - where o.OrderID < 10800 - select o) - .AsNoTracking(); - - Assert.Equal( - CoreStrings.IncludeWithCycle("Customer", "Orders"), - async - ? (await Assert.ThrowsAsync(() => query.ToListAsync())).Message - : Assert.Throws(() => query.ToList()).Message); - } - - [ConditionalTheory] - [InlineData(false, false)] - [InlineData(true, false)] - [InlineData(false, true)] - [InlineData(true, true)] - public virtual async Task NoTracking_Include_with_cycles_does_not_throw_when_performing_identity_resolution(bool useString, bool async) - { - using var context = CreateContext(); - var query = (from o in (useString - ? context.Orders.Include("Customer.Orders") - : context.Orders.Include(o => o.Customer.Orders)) - where o.OrderID < 10800 - select o) - .PerformIdentityResolution(); - - var result = async - ? await query.ToListAsync() - : query.ToList(); - - Assert.Empty(context.ChangeTracker.Entries()); - foreach (var order in result) - { - Assert.NotNull(order.Customer); - Assert.Same(order, order.Customer.Orders.First(o => o.OrderID == order.OrderID)); - } - } - - private static void CheckIsLoaded( - NorthwindContext context, - Customer customer, - bool ordersLoaded, - bool orderDetailsLoaded, - bool productLoaded) - { - context.ChangeTracker.AutoDetectChangesEnabled = false; - - Assert.Equal(ordersLoaded, context.Entry(customer).Collection(e => e.Orders).IsLoaded); - if (customer.Orders != null) - { - foreach (var order in customer.Orders) + return AssertFirst( + async, + ss => (from c in ss.Set().Include(e => e.Orders).ThenInclude(e => e.OrderDetails) + where c.CustomerID.StartsWith("A") + orderby c.CustomerID + select new { c.CustomerID, Orders = c.Orders.ToList() }).Skip(1), + asserter: (e, a) => { - Assert.Equal(ordersLoaded, context.Entry(order).Reference(e => e.Customer).IsLoaded); - - Assert.Equal(orderDetailsLoaded, context.Entry(order).Collection(e => e.OrderDetails).IsLoaded); - if (order.OrderDetails != null) - { - foreach (var orderDetail in order.OrderDetails) - { - Assert.Equal(orderDetailsLoaded, context.Entry(orderDetail).Reference(e => e.Order).IsLoaded); - - Assert.Equal(productLoaded, context.Entry(orderDetail).Reference(e => e.Product).IsLoaded); - if (orderDetail.Product != null) - { - Assert.False(context.Entry(orderDetail.Product).Collection(e => e.OrderDetails).IsLoaded); - } - } - } - } - } + AssertEqual(e.CustomerID, a.CustomerID); + AssertCollection(e.Orders, a.Orders, + elementAsserter: (eo, ao) => AssertInclude(eo, ao, new ExpectedInclude(o => o.OrderDetails))); + }, + entryCount: 14); } - private static void CheckIsLoaded( - NorthwindContext context, - Product product, - bool orderDetailsLoaded, - bool orderLoaded) - { - context.ChangeTracker.AutoDetectChangesEnabled = false; - - Assert.Equal(orderDetailsLoaded, context.Entry(product).Collection(e => e.OrderDetails).IsLoaded); - - if (product.OrderDetails != null) - { - foreach (var orderDetail in product.OrderDetails) - { - Assert.Equal(orderDetailsLoaded, context.Entry(orderDetail).Reference(e => e.Product).IsLoaded); - - Assert.Equal(orderLoaded, context.Entry(orderDetail).Reference(e => e.Order).IsLoaded); - if (orderDetail.Order != null) - { - Assert.False(context.Entry(orderDetail.Order).Collection(e => e.OrderDetails).IsLoaded); - } - } - } - } - - private static void CheckIsLoaded( - NorthwindContext context, - Order order, - bool orderDetailsLoaded, - bool productLoaded, - bool customerLoaded, - bool ordersLoaded) + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Multi_level_includes_are_applied_with_take(bool async) { - context.ChangeTracker.AutoDetectChangesEnabled = false; - - Assert.Equal(orderDetailsLoaded, context.Entry(order).Collection(e => e.OrderDetails).IsLoaded); - if (order.OrderDetails != null) - { - foreach (var orderDetail in order.OrderDetails) - { - Assert.Equal(orderDetailsLoaded, context.Entry(orderDetail).Reference(e => e.Order).IsLoaded); - - Assert.Equal(productLoaded, context.Entry(orderDetail).Reference(e => e.Product).IsLoaded); - if (orderDetail.Product != null) - { - Assert.False(context.Entry(orderDetail.Product).Collection(e => e.OrderDetails).IsLoaded); - } - } - } - - Assert.Equal(customerLoaded, context.Entry(order).Reference(e => e.Customer).IsLoaded); - if (order.Customer != null) - { - Assert.Equal(ordersLoaded, context.Entry(order.Customer).Collection(e => e.Orders).IsLoaded); - if (ordersLoaded - && order.Customer.Orders != null) + return AssertFirst( + async, + ss => (from c in ss.Set().Include(e => e.Orders).ThenInclude(e => e.OrderDetails) + where c.CustomerID.StartsWith("A") + orderby c.CustomerID + select new { c.CustomerID, Orders = c.Orders.ToList() }).Take(1), + asserter: (e, a) => { - foreach (var backOrder in order.Customer.Orders) - { - Assert.Equal(ordersLoaded, context.Entry(backOrder).Reference(e => e.Customer).IsLoaded); - } - } - } + AssertEqual(e.CustomerID, a.CustomerID); + AssertCollection(e.Orders, a.Orders, + elementAsserter: (eo, ao) => AssertInclude(eo, ao, new ExpectedInclude(o => o.OrderDetails))); + }, + entryCount: 18); } - private static void CheckIsLoaded( - NorthwindContext context, - OrderDetail orderDetail, - bool orderLoaded, - bool productLoaded, - bool customerLoaded, - bool ordersLoaded) + [ConditionalTheory] + [MemberData(nameof(IsAsyncData))] + public virtual Task Multi_level_includes_are_applied_with_skip_take(bool async) { - context.ChangeTracker.AutoDetectChangesEnabled = false; - - Assert.Equal(orderLoaded, context.Entry(orderDetail).Reference(e => e.Order).IsLoaded); - if (orderDetail.Order != null) - { - Assert.False(context.Entry(orderDetail.Order).Collection(e => e.OrderDetails).IsLoaded); - - Assert.Equal(customerLoaded, context.Entry(orderDetail.Order).Reference(e => e.Customer).IsLoaded); - if (orderDetail.Order.Customer != null) + return AssertFirst( + async, + ss => (from c in ss.Set().Include(e => e.Orders).ThenInclude(e => e.OrderDetails) + where c.CustomerID.StartsWith("A") + orderby c.CustomerID + select new { c.CustomerID, Orders = c.Orders.ToList() }).Skip(1).Take(1), + asserter: (e, a) => { - Assert.Equal(ordersLoaded, context.Entry(orderDetail.Order.Customer).Collection(e => e.Orders).IsLoaded); - if (ordersLoaded - && orderDetail.Order.Customer.Orders != null) - { - foreach (var backOrder in orderDetail.Order.Customer.Orders) - { - Assert.Equal(ordersLoaded, context.Entry(backOrder).Reference(e => e.Customer).IsLoaded); - } - } - } - } - - Assert.Equal(productLoaded, context.Entry(orderDetail).Reference(e => e.Product).IsLoaded); - if (orderDetail.Product != null) - { - Assert.False(context.Entry(orderDetail.Product).Collection(e => e.OrderDetails).IsLoaded); - } - } + AssertEqual(e.CustomerID, a.CustomerID); + AssertCollection(e.Orders, a.Orders, + elementAsserter: (eo, ao) => AssertInclude(eo, ao, new ExpectedInclude(o => o.OrderDetails))); + }, + entryCount: 14); + } + + // TODO: move to notracking test base + //[ConditionalTheory] + //[MemberData(nameof(IsAsyncData))] + //public virtual async Task NoTracking_Include_with_cycles_throws(bool async) + //{ + // return AssertQuery( + //async, + //ss => , + //entryCount: 0); + + // var query = (from o in ss.Set().Include(o => o.Customer.Orders) + // where o.OrderID < 10800 + // select o) + // .AsNoTracking(); + + // Assert.Equal( + // CoreStrings.IncludeWithCycle("Customer", "Orders"), + // async + // ? (await Assert.ThrowsAsync(() => query.ToListAsync())).Message + // : Assert.Throws(() => query.ToList()).Message); + //} + + //[ConditionalTheory] + //[MemberData(nameof(IsAsyncData))] + //public virtual async Task NoTracking_Include_with_cycles_does_not_throw_when_performing_identity_resolution(bool async) + //{ + // return AssertQuery( + //async, + //ss => , + //entryCount: 0); + + // var query = (from o in (async + // ? ss.Set().Include("Customer.Orders") + // : ss.Set().Include(o => o.Customer.Orders)) + // where o.OrderID < 10800 + // select o) + // .PerformIdentityResolution(); + + // var result = async + // ? await query.ToListAsync() + // : query.ToList(); + + // Assert.Empty(ss.ChangeTracker.Entries()); + // foreach (var order in result) + // { + // Assert.NotNull(order.Customer); + // Assert.Same(order, order.Customer.Orders.First(o => o.OrderID == order.OrderID)); + // } + //} protected virtual void ClearLog() { diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeAsyncQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeAsyncQuerySqlServerTest.cs deleted file mode 100644 index a2a9d7cb697..00000000000 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeAsyncQuerySqlServerTest.cs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore.TestUtilities; -using Xunit.Abstractions; - -namespace Microsoft.EntityFrameworkCore.Query -{ - public class NorthwindIncludeAsyncQuerySqlServerTest : NorthwindIncludeAsyncQueryTestBase> - { - public NorthwindIncludeAsyncQuerySqlServerTest(NorthwindQuerySqlServerFixture fixture, ITestOutputHelper testOutputHelper) - : base(fixture) - { - Fixture.TestSqlLoggerFactory.Clear(); - //Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); - } - - public override async Task Include_collection_order_by_subquery() - { - await base.Include_collection_order_by_subquery(); - - AssertSql( - @"SELECT [t].[CustomerID], [t].[Address], [t].[City], [t].[CompanyName], [t].[ContactName], [t].[ContactTitle], [t].[Country], [t].[Fax], [t].[Phone], [t].[PostalCode], [t].[Region], [o0].[OrderID], [o0].[CustomerID], [o0].[EmployeeID], [o0].[OrderDate] -FROM ( - SELECT TOP(1) [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], ( - SELECT TOP(1) [o].[OrderDate] - FROM [Orders] AS [o] - WHERE [c].[CustomerID] = [o].[CustomerID] - ORDER BY [o].[EmployeeID]) AS [c] - FROM [Customers] AS [c] - WHERE [c].[CustomerID] = N'ALFKI' - ORDER BY ( - SELECT TOP(1) [o].[OrderDate] - FROM [Orders] AS [o] - WHERE [c].[CustomerID] = [o].[CustomerID] - ORDER BY [o].[EmployeeID]) -) AS [t] -LEFT JOIN [Orders] AS [o0] ON [t].[CustomerID] = [o0].[CustomerID] -ORDER BY [t].[c], [t].[CustomerID], [o0].[OrderID]"); - } - - public override async Task Include_collection_then_include_collection() - { - await base.Include_collection_then_include_collection(); - - AssertSql( - @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [t].[OrderID], [t].[CustomerID], [t].[EmployeeID], [t].[OrderDate], [t].[OrderID0], [t].[ProductID], [t].[Discount], [t].[Quantity], [t].[UnitPrice] -FROM [Customers] AS [c] -LEFT JOIN ( - SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [o0].[OrderID] AS [OrderID0], [o0].[ProductID], [o0].[Discount], [o0].[Quantity], [o0].[UnitPrice] - FROM [Orders] AS [o] - LEFT JOIN [Order Details] AS [o0] ON [o].[OrderID] = [o0].[OrderID] -) AS [t] ON [c].[CustomerID] = [t].[CustomerID] -ORDER BY [c].[CustomerID], [t].[OrderID], [t].[OrderID0], [t].[ProductID]"); - } - - private void AssertSql(params string[] expected) - => Fixture.TestSqlLoggerFactory.AssertBaseline(expected); - } -} diff --git a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeQuerySqlServerTest.cs b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeQuerySqlServerTest.cs index 093e42aa074..369b0f0a677 100644 --- a/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeQuerySqlServerTest.cs +++ b/test/EFCore.SqlServer.FunctionalTests/Query/NorthwindIncludeQuerySqlServerTest.cs @@ -17,9 +17,9 @@ public NorthwindIncludeQuerySqlServerTest(NorthwindQuerySqlServerFixture 2) +WHERE [c].[ContactTitle] = N'Owner' ORDER BY [c].[CustomerID]"); } - public override void Include_with_take(bool useString) + public override async Task Include_with_take(bool async) { - base.Include_with_take(useString); + await base.Include_with_take(async); AssertSql( @"@__p_0='10' @@ -959,15 +881,15 @@ public override void Include_with_take(bool useString) FROM ( SELECT TOP(@__p_0) [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] FROM [Customers] AS [c] - ORDER BY [c].[City] DESC + ORDER BY [c].[ContactName] DESC ) AS [t] LEFT JOIN [Orders] AS [o] ON [t].[CustomerID] = [o].[CustomerID] -ORDER BY [t].[City] DESC, [t].[CustomerID], [o].[OrderID]"); +ORDER BY [t].[ContactName] DESC, [t].[CustomerID], [o].[OrderID]"); } - public override void Include_with_skip(bool useString) + public override async Task Include_with_skip(bool async) { - base.Include_with_skip(useString); + await base.Include_with_skip(async); AssertSql( @"@__p_0='80' @@ -983,9 +905,9 @@ OFFSET @__p_0 ROWS ORDER BY [t].[ContactName], [t].[CustomerID], [o].[OrderID]"); } - public override void Include_collection_with_multiple_conditional_order_by(bool useString) + public override async Task Include_collection_with_multiple_conditional_order_by(bool async) { - base.Include_collection_with_multiple_conditional_order_by(useString); + await base.Include_collection_with_multiple_conditional_order_by(async); AssertSql( @"@__p_0='5' @@ -1013,9 +935,9 @@ ELSE N'' ORDER BY [t].[c], [t].[c0], [t].[OrderID], [t].[CustomerID0], [o0].[OrderID], [o0].[ProductID]"); } - public override void Then_include_collection_order_by_collection_column(bool useString) + public override async Task Then_include_collection_order_by_collection_column(bool async) { - base.Then_include_collection_order_by_collection_column(useString); + await base.Then_include_collection_order_by_collection_column(async); AssertSql( @"SELECT [t].[CustomerID], [t].[Address], [t].[City], [t].[CompanyName], [t].[ContactName], [t].[ContactTitle], [t].[Country], [t].[Fax], [t].[Phone], [t].[PostalCode], [t].[Region], [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate], [t0].[OrderID0], [t0].[ProductID], [t0].[Discount], [t0].[Quantity], [t0].[UnitPrice] @@ -1041,9 +963,9 @@ FROM [Orders] AS [o0] ORDER BY [t].[c] DESC, [t].[CustomerID], [t0].[OrderID], [t0].[OrderID0], [t0].[ProductID]"); } - public override void Include_collection_with_conditional_order_by(bool useString) + public override async Task Include_collection_with_conditional_order_by(bool async) { - base.Include_collection_with_conditional_order_by(useString); + await base.Include_collection_with_conditional_order_by(async); AssertSql( @"SELECT [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region], [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] @@ -1055,9 +977,9 @@ ELSE 2 END, [c].[CustomerID], [o].[OrderID]"); } - public override void Include_reference_distinct_is_server_evaluated(bool useString) + public override async Task Include_reference_distinct_is_server_evaluated(bool async) { - base.Include_reference_distinct_is_server_evaluated(useString); + await base.Include_reference_distinct_is_server_evaluated(async); AssertSql( @"SELECT [t].[OrderID], [t].[CustomerID], [t].[EmployeeID], [t].[OrderDate], [c].[CustomerID], [c].[Address], [c].[City], [c].[CompanyName], [c].[ContactName], [c].[ContactTitle], [c].[Country], [c].[Fax], [c].[Phone], [c].[PostalCode], [c].[Region] @@ -1069,9 +991,9 @@ WHERE [o].[OrderID] < 10250 LEFT JOIN [Customers] AS [c] ON [t].[CustomerID] = [c].[CustomerID]"); } - public override void Include_collection_distinct_is_server_evaluated(bool useString) + public override async Task Include_collection_distinct_is_server_evaluated(bool async) { - base.Include_collection_distinct_is_server_evaluated(useString); + await base.Include_collection_distinct_is_server_evaluated(async); AssertSql( @"SELECT [t].[CustomerID], [t].[Address], [t].[City], [t].[CompanyName], [t].[ContactName], [t].[ContactTitle], [t].[Country], [t].[Fax], [t].[Phone], [t].[PostalCode], [t].[Region], [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate] @@ -1084,9 +1006,9 @@ WHERE [c].[CustomerID] LIKE N'A%' ORDER BY [t].[CustomerID], [o].[OrderID]"); } - public override void Include_collection_OrderBy_object(bool useString) + public override async Task Include_collection_OrderBy_object(bool async) { - base.Include_collection_OrderBy_object(useString); + await base.Include_collection_OrderBy_object(async); AssertSql( @"SELECT [o].[OrderID], [o].[CustomerID], [o].[EmployeeID], [o].[OrderDate], [o0].[OrderID], [o0].[ProductID], [o0].[Discount], [o0].[Quantity], [o0].[UnitPrice] @@ -1096,9 +1018,9 @@ WHERE [o].[OrderID] < 10250 ORDER BY [o].[OrderID], [o0].[OrderID], [o0].[ProductID]"); } - public override void Include_collection_OrderBy_empty_list_contains(bool useString) + public override async Task Include_collection_OrderBy_empty_list_contains(bool async) { - base.Include_collection_OrderBy_empty_list_contains(useString); + await base.Include_collection_OrderBy_empty_list_contains(async); AssertSql( @"@__p_1='1' @@ -1123,9 +1045,9 @@ OFFSET @__p_1 ROWS ORDER BY [t].[c], [t].[CustomerID]"); } - public override void Include_collection_OrderBy_empty_list_does_not_contains(bool useString) + public override async Task Include_collection_OrderBy_empty_list_does_not_contains(bool async) { - base.Include_collection_OrderBy_empty_list_does_not_contains(useString); + await base.Include_collection_OrderBy_empty_list_does_not_contains(async); AssertSql( @"@__p_1='1' @@ -1150,9 +1072,9 @@ OFFSET @__p_1 ROWS ORDER BY [t].[c], [t].[CustomerID]"); } - public override void Include_collection_OrderBy_list_contains(bool useString) + public override async Task Include_collection_OrderBy_list_contains(bool async) { - base.Include_collection_OrderBy_list_contains(useString); + await base.Include_collection_OrderBy_list_contains(async); AssertSql( @"@__p_1='1' @@ -1175,9 +1097,9 @@ OFFSET @__p_1 ROWS ORDER BY [t].[c], [t].[CustomerID], [o].[OrderID]"); } - public override void Include_collection_OrderBy_list_does_not_contains(bool useString) + public override async Task Include_collection_OrderBy_list_does_not_contains(bool async) { - base.Include_collection_OrderBy_list_does_not_contains(useString); + await base.Include_collection_OrderBy_list_does_not_contains(async); AssertSql( @"@__p_1='1' @@ -1200,10 +1122,9 @@ OFFSET @__p_1 ROWS ORDER BY [t].[c], [t].[CustomerID], [o].[OrderID]"); } - public override async Task Include_is_not_ignored_when_projection_contains_client_method_and_complex_expression( - bool useString, bool async) + public override async Task Include_is_not_ignored_when_projection_contains_client_method_and_complex_expression(bool async) { - await base.Include_is_not_ignored_when_projection_contains_client_method_and_complex_expression(useString, async); + await base.Include_is_not_ignored_when_projection_contains_client_method_and_complex_expression(async); AssertSql( @"SELECT CASE @@ -1216,9 +1137,9 @@ FROM [Employees] AS [e] ORDER BY [e].[EmployeeID]"); } - public override async Task Multi_level_includes_are_applied_with_skip(bool useString, bool async) + public override async Task Multi_level_includes_are_applied_with_skip(bool async) { - await base.Multi_level_includes_are_applied_with_skip(useString, async); + await base.Multi_level_includes_are_applied_with_skip(async); AssertSql( @"@__p_0='1' @@ -1239,9 +1160,9 @@ FROM [Orders] AS [o] ORDER BY [t].[CustomerID], [t0].[OrderID], [t0].[OrderID0], [t0].[ProductID]"); } - public override async Task Multi_level_includes_are_applied_with_take(bool useString, bool async) + public override async Task Multi_level_includes_are_applied_with_take(bool async) { - await base.Multi_level_includes_are_applied_with_take(useString, async); + await base.Multi_level_includes_are_applied_with_take(async); AssertSql( @"@__p_0='1' @@ -1265,9 +1186,9 @@ FROM [Orders] AS [o] ORDER BY [t0].[CustomerID], [t1].[OrderID], [t1].[OrderID0], [t1].[ProductID]"); } - public override async Task Multi_level_includes_are_applied_with_skip_take(bool useString, bool async) + public override async Task Multi_level_includes_are_applied_with_skip_take(bool async) { - await base.Multi_level_includes_are_applied_with_skip_take(useString, async); + await base.Multi_level_includes_are_applied_with_skip_take(async); AssertSql( @"@__p_0='1' diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindIncludeAsyncQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindIncludeAsyncQuerySqliteTest.cs deleted file mode 100644 index 40878d6d907..00000000000 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindIncludeAsyncQuerySqliteTest.cs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright (c) .NET Foundation. All rights reserved. -// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. - -namespace Microsoft.EntityFrameworkCore.Query -{ - public class NorthwindIncludeAsyncQuerySqliteTest : NorthwindIncludeAsyncQueryTestBase - { - public NorthwindIncludeAsyncQuerySqliteTest(IncludeSqliteFixture fixture) - : base(fixture) - { - } - } -} diff --git a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindIncludeQuerySqliteTest.cs b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindIncludeQuerySqliteTest.cs index cc80bc3d6f9..48ef2a78c2a 100644 --- a/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindIncludeQuerySqliteTest.cs +++ b/test/EFCore.Sqlite.FunctionalTests/Query/NorthwindIncludeQuerySqliteTest.cs @@ -1,7 +1,7 @@ // Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. -using Microsoft.EntityFrameworkCore.TestUtilities; +using System.Threading.Tasks; using Xunit.Abstractions; namespace Microsoft.EntityFrameworkCore.Query @@ -14,19 +14,9 @@ public NorthwindIncludeQuerySqliteTest(IncludeSqliteFixture fixture, ITestOutput //TestSqlLoggerFactory.CaptureOutput(testOutputHelper); } - [SqliteVersionCondition(Min = "3.8.8", SkipReason = "Distinct & Order By gives incorrect result in older version of Sqlite.")] - public override void Include_collection_order_by_non_key_with_take(bool useString) - { - base.Include_collection_order_by_non_key_with_take(useString); - } - // Sqlite does not support Apply operations - public override void Include_collection_with_cross_apply_with_filter(bool useString) - { - } + public override Task Include_collection_with_cross_apply_with_filter(bool async) => Task.CompletedTask; - public override void Include_collection_with_outer_apply_with_filter(bool useString) - { - } + public override Task Include_collection_with_outer_apply_with_filter(bool async) => Task.CompletedTask; } }