Upgrade DbContextPooling tests

pull/160/head
Christopher Jolly 2 years ago
parent 0d5676a4e5
commit 53bdc99453

@ -1,35 +1,35 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using EntityFrameworkCore.Jet.Data;
using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using EntityFrameworkCore.Jet.Data;
using EntityFrameworkCore.Jet.FunctionalTests.Query;
using EntityFrameworkCore.Jet.FunctionalTests.TestUtilities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Diagnostics;
using Microsoft.EntityFrameworkCore.Diagnostics.Internal;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.EntityFrameworkCore.TestUtilities;
using Microsoft.EntityFrameworkCore.TestUtilities.Xunit;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
using Xunit.Abstractions;
using Microsoft.EntityFrameworkCore.Infrastructure;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Collections.Specialized;
// ReSharper disable MethodHasAsyncOverload
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedAutoPropertyAccessor.Local
// ReSharper disable UnusedMember.Local
// ReSharper disable ClassNeverInstantiated.Local
// ReSharper disable VirtualMemberCallInConstructor
namespace EntityFrameworkCore.Jet.FunctionalTests
{
namespace EntityFrameworkCore.Jet.FunctionalTests;
public class DbContextPoolingTest : IClassFixture<NorthwindQueryJetFixture<NoopModelCustomizer>>
{
private static DbContextOptionsBuilder<TContext> ConfigureOptions<TContext>(DbContextOptionsBuilder<TContext> optionsBuilder)
@ -43,19 +43,51 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
.UseJet(JetNorthwindTestStoreFactory.NorthwindConnectionString)
.EnableServiceProviderCaching(false);
private static IServiceProvider BuildServiceProvider<TContextService, TContext>()
private static IServiceProvider BuildServiceProvider<TContextService, TContext>(Action<DbContextOptionsBuilder> optionsAction = null)
where TContextService : class
where TContext : DbContext, TContextService
=> new ServiceCollection()
.AddDbContextPool<TContextService, TContext>(ob => ConfigureOptions(ob))
.AddDbContextPool<ISecondContext, SecondContext>(ob => ConfigureOptions(ob))
.AddDbContextPool<TContextService, TContext>(
ob =>
{
var builder = ConfigureOptions(ob);
if (optionsAction != null)
{
optionsAction(builder);
}
})
.AddDbContextPool<ISecondContext, SecondContext>(
ob =>
{
var builder = ConfigureOptions(ob);
if (optionsAction != null)
{
optionsAction(builder);
}
})
.BuildServiceProvider(validateScopes: true);
private static IServiceProvider BuildServiceProvider<TContext>()
private static IServiceProvider BuildServiceProvider<TContext>(Action<DbContextOptionsBuilder> optionsAction = null)
where TContext : DbContext
=> new ServiceCollection()
.AddDbContextPool<TContext>(ob => ConfigureOptions(ob))
.AddDbContextPool<SecondContext>(ob => ConfigureOptions(ob))
.AddDbContextPool<TContext>(
ob =>
{
var builder = ConfigureOptions(ob);
if (optionsAction != null)
{
optionsAction(builder);
}
})
.AddDbContextPool<SecondContext>(
ob =>
{
var builder = ConfigureOptions(ob);
if (optionsAction != null)
{
optionsAction(builder);
}
})
.BuildServiceProvider(validateScopes: true);
private static IServiceProvider BuildServiceProviderWithFactory<TContext>()
@ -153,7 +185,10 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
public DbSet<Customer> Customers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.Entity<Customer>().ToTable("Customers");
{
modelBuilder.Entity<Customer>().ToTable("Customers");
modelBuilder.Entity<Order>().ToTable("Orders");
}
public override void Dispose()
{
@ -173,19 +208,26 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
public DbSet<Customer> Customers { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
=> modelBuilder.Entity<Customer>().ToTable("Customers");
{
modelBuilder.Entity<Customer>().ToTable("Customers");
modelBuilder.Entity<Order>().ToTable("Orders");
}
}
public class Customer
{
public string CustomerId { get; set; }
public string CompanyName { get; set; }
public ILazyLoader LazyLoader { get; set; }
public ObservableCollection<Order> Orders { get; } = new();
}
public class Order
{
public string OrderId { get; set; }
public int OrderId { get; set; }
public ILazyLoader LazyLoader { get; set; }
public string CustomerId { get; set; }
public Customer Customer { get; set; }
}
private interface ISecondContext
@ -424,7 +466,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
}
[ConditionalFact]
public void Throws_when_pooled_context_constructor_has_more_than_one_parameter()
public void Throws_when_pooled_context_constructor_has_second_parameter_that_cannot_be_resolved_from_service_provider()
{
var serviceProvider
= new ServiceCollection().AddDbContextPool<TwoParameterConstructorContext>(_ => { })
@ -432,21 +474,22 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
using var scope = serviceProvider.CreateScope();
Assert.Equal(
CoreStrings.PoolingContextCtorError(nameof(TwoParameterConstructorContext)),
Assert.Throws<InvalidOperationException>(() => scope.ServiceProvider.GetService<TwoParameterConstructorContext>()).Message);
Assert.Throws<InvalidOperationException>(() => scope.ServiceProvider.GetService<TwoParameterConstructorContext>());
}
private class TwoParameterConstructorContext : DbContext
{
public string StringParameter { get; }
public TwoParameterConstructorContext(DbContextOptions options, string x)
: base(options)
{
StringParameter = x;
}
}
[ConditionalFact]
public void Throws_when_pooled_context_constructor_wrong_parameter()
public void Throws_when_pooled_context_constructor_has_single_parameter_that_cannot_be_resolved_from_service_provider()
{
var serviceProvider
= new ServiceCollection().AddDbContextPool<WrongParameterConstructorContext>(_ => { })
@ -454,10 +497,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
using var scope = serviceProvider.CreateScope();
Assert.Equal(
CoreStrings.PoolingContextCtorError(nameof(WrongParameterConstructorContext)),
Assert.Throws<InvalidOperationException>(() => scope.ServiceProvider.GetService<WrongParameterConstructorContext>())
.Message);
Assert.Throws<InvalidOperationException>(() => scope.ServiceProvider.GetService<WrongParameterConstructorContext>());
}
private class WrongParameterConstructorContext : DbContext
@ -468,6 +508,35 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
}
}
[ConditionalFact]
public void Throws_when_pooled_context_constructor_has_scoped_service()
{
var serviceProvider
= new ServiceCollection()
.AddDbContextPool<TwoParameterConstructorContext>(_ => { })
.AddScoped(sp => "string")
.BuildServiceProvider(validateScopes: true);
using var scope = serviceProvider.CreateScope();
Assert.Throws<InvalidOperationException>(() => scope.ServiceProvider.GetService<TwoParameterConstructorContext>());
}
[ConditionalFact]
public void Does_not_throw_when_pooled_context_constructor_has_singleton_service()
{
var serviceProvider
= new ServiceCollection()
.AddDbContextPool<TwoParameterConstructorContext>(_ => { })
.AddSingleton("string")
.BuildServiceProvider(validateScopes: true);
using var scope = serviceProvider.CreateScope();
var context = scope.ServiceProvider.GetService<TwoParameterConstructorContext>();
Assert.Equal("string", context.StringParameter);
}
[ConditionalFact]
public void Does_not_throw_when_parameterless_and_correct_constructor()
{
@ -513,16 +582,22 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
}
}
[ConditionalFact]
public void Can_pool_non_derived_context()
[ConditionalTheory]
[InlineData(false, false)]
[InlineData(true, false)]
[InlineData(false, true)]
[InlineData(true, true)]
public async Task Can_pool_non_derived_context(bool useFactory, bool async)
{
var serviceProvider = BuildServiceProvider<DbContext>();
var serviceProvider = useFactory
? BuildServiceProviderWithFactory<DbContext>()
: BuildServiceProvider<DbContext>();
var serviceScope1 = serviceProvider.CreateScope();
var context1 = serviceScope1.ServiceProvider.GetService<DbContext>();
var context1 = await GetContextAsync(serviceScope1);
var serviceScope2 = serviceProvider.CreateScope();
var context2 = serviceScope2.ServiceProvider.GetService<DbContext>();
var context2 = await GetContextAsync(serviceScope2);
Assert.NotSame(context1, context2);
@ -535,8 +610,18 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.Equal(1, id1.Lease);
Assert.Equal(1, id2.Lease);
serviceScope1.Dispose();
serviceScope2.Dispose();
if (useFactory)
{
await Dispose(context1, async);
}
await Dispose(serviceScope1, async);
await Dispose(serviceScope2, async);
if (useFactory)
{
await Dispose(context2, async);
}
var id1d = context1.ContextId;
var id2d = context2.ContextId;
@ -547,7 +632,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.Equal(1, id2d.Lease);
var serviceScope3 = serviceProvider.CreateScope();
var context3 = serviceScope3.ServiceProvider.GetService<DbContext>();
var context3 = await GetContextAsync(serviceScope3);
var id1r = context3.ContextId;
@ -558,7 +643,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.Equal(2, id1r.Lease);
var serviceScope4 = serviceProvider.CreateScope();
var context4 = serviceScope4.ServiceProvider.GetService<DbContext>();
var context4 = await GetContextAsync(serviceScope4);
var id2r = context4.ContextId;
@ -567,17 +652,26 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.NotEqual(default, id2r.InstanceId);
Assert.NotEqual(id2, id2r);
Assert.Equal(2, id2r.Lease);
async Task<DbContext> GetContextAsync(IServiceScope serviceScope)
=> useFactory
? async
? await serviceScope.ServiceProvider.GetService<IDbContextFactory<DbContext>>()!.CreateDbContextAsync()
: serviceScope.ServiceProvider.GetService<IDbContextFactory<DbContext>>()!.CreateDbContext()
: serviceScope.ServiceProvider.GetService<DbContext>();
}
[ConditionalFact]
public void ContextIds_make_sense_when_not_pooling()
[ConditionalTheory]
[InlineData(false)]
[InlineData(true)]
public async Task ContextIds_make_sense_when_not_pooling(bool async)
{
var serviceProvider = new ServiceCollection()
.AddDbContext<DbContext>(
ob
=> ob.UseJet(JetNorthwindTestStoreFactory.NorthwindConnectionString, TestEnvironment.DataAccessProviderFactory)
=> ob.UseJet(JetNorthwindTestStoreFactory.NorthwindConnectionString)
.EnableServiceProviderCaching(false))
.BuildServiceProvider();
.BuildServiceProvider(validateScopes: true);
var serviceScope1 = serviceProvider.CreateScope();
var context1 = serviceScope1.ServiceProvider.GetService<DbContext>();
@ -587,8 +681,8 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.NotSame(context1, context2);
var id1 = context1.ContextId;
var id2 = context2.ContextId;
var id1 = context1!.ContextId;
var id2 = context2!.ContextId;
Assert.NotEqual(default, id1.InstanceId);
Assert.NotEqual(default, id2.InstanceId);
@ -597,8 +691,8 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.Equal(0, id1.Lease);
Assert.Equal(0, id2.Lease);
serviceScope1.Dispose();
serviceScope2.Dispose();
await Dispose(serviceScope1, async);
await Dispose(serviceScope2, async);
var id1d = context1.ContextId;
var id2d = context2.ContextId;
@ -632,9 +726,11 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
}
[ConditionalTheory]
[InlineData(true)]
[InlineData(false)]
public void Contexts_are_pooled(bool useInterface)
[InlineData(false, false)]
[InlineData(true, false)]
[InlineData(false, true)]
[InlineData(true, true)]
public async Task Contexts_are_pooled(bool useInterface, bool async)
{
var serviceProvider = useInterface
? BuildServiceProvider<IPooledContext, PooledContext>()
@ -665,8 +761,9 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.NotSame(context1, context2);
Assert.NotSame(secondContext1, secondContext2);
serviceScope1.Dispose();
serviceScope2.Dispose();
await Dispose(serviceScope1, async);
await Dispose(serviceScope2, async);
var serviceScope3 = serviceProvider.CreateScope();
var scopedProvider3 = serviceScope3.ServiceProvider;
@ -695,6 +792,10 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.Same(context2, context4);
Assert.Same(secondContext2, secondContext4);
await Dispose(serviceScope3, async);
await Dispose(serviceScope4, async);
}
[ConditionalTheory]
@ -702,11 +803,64 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
[InlineData(true, false)]
[InlineData(false, true)]
[InlineData(true, true)]
public async Task Context_configuration_is_reset(bool useInterface, bool async)
public async Task Contexts_are_pooled_with_factory(bool async, bool withDependencyInjection)
{
var factory = BuildFactory<PooledContext>(withDependencyInjection);
var context1 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
var secondContext1 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
var context2 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
var secondContext2 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
Assert.NotSame(context1, context2);
Assert.NotSame(secondContext1, secondContext2);
await Dispose(context1, async);
await Dispose(secondContext1, async);
await Dispose(context2, async);
await Dispose(secondContext2, async);
var context3 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
var secondContext3 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
Assert.Same(context1, context3);
Assert.Same(secondContext1, secondContext3);
var context4 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
var secondContext4 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
Assert.Same(context2, context4);
Assert.Same(secondContext2, secondContext4);
await Dispose(context1, async);
await Dispose(secondContext1, async);
await Dispose(context2, async);
await Dispose(secondContext2, async);
}
[ConditionalTheory]
[InlineData(false, false, null)]
[InlineData(true, false, null)]
[InlineData(false, true, null)]
[InlineData(true, true, null)]
[InlineData(false, false, QueryTrackingBehavior.TrackAll)]
[InlineData(true, false, QueryTrackingBehavior.TrackAll)]
[InlineData(false, true, QueryTrackingBehavior.TrackAll)]
[InlineData(true, true, QueryTrackingBehavior.TrackAll)]
[InlineData(false, false, QueryTrackingBehavior.NoTracking)]
[InlineData(true, false, QueryTrackingBehavior.NoTracking)]
[InlineData(false, true, QueryTrackingBehavior.NoTracking)]
[InlineData(true, true, QueryTrackingBehavior.NoTracking)]
[InlineData(false, false, QueryTrackingBehavior.NoTrackingWithIdentityResolution)]
[InlineData(true, false, QueryTrackingBehavior.NoTrackingWithIdentityResolution)]
[InlineData(false, true, QueryTrackingBehavior.NoTrackingWithIdentityResolution)]
[InlineData(true, true, QueryTrackingBehavior.NoTrackingWithIdentityResolution)]
public async Task Context_configuration_is_reset(bool useInterface, bool async, QueryTrackingBehavior? queryTrackingBehavior)
{
var serviceProvider = useInterface
? BuildServiceProvider<IPooledContext, PooledContext>()
: BuildServiceProvider<PooledContext>();
? BuildServiceProvider<IPooledContext, PooledContext>(b => UseQueryTrackingBehavior(b, queryTrackingBehavior))
: BuildServiceProvider<PooledContext>(b => UseQueryTrackingBehavior(b, queryTrackingBehavior));
var serviceScope = serviceProvider.CreateScope();
var scopedProvider = serviceScope.ServiceProvider;
@ -768,7 +922,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.False(context2!.ChangeTracker.AutoDetectChangesEnabled);
Assert.False(context2.ChangeTracker.LazyLoadingEnabled);
Assert.Equal(QueryTrackingBehavior.TrackAll, context2.ChangeTracker.QueryTrackingBehavior);
Assert.Equal(queryTrackingBehavior ?? QueryTrackingBehavior.TrackAll, context2.ChangeTracker.QueryTrackingBehavior);
Assert.Equal(CascadeTiming.Never, context2.ChangeTracker.CascadeDeleteTiming);
Assert.Equal(CascadeTiming.Never, context2.ChangeTracker.DeleteOrphansTiming);
Assert.Equal(AutoTransactionBehavior.Never, context2.Database.AutoTransactionBehavior);
@ -809,11 +963,17 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
}
[ConditionalTheory]
[InlineData(false)]
[InlineData(true)]
public async Task Uninitialized_context_configuration_is_reset_properly(bool async)
{
var serviceProvider = BuildServiceProvider<SecondContext>();
[InlineData(false, null)]
[InlineData(true, null)]
[InlineData(false, QueryTrackingBehavior.TrackAll)]
[InlineData(true, QueryTrackingBehavior.TrackAll)]
[InlineData(false, QueryTrackingBehavior.NoTracking)]
[InlineData(true, QueryTrackingBehavior.NoTracking)]
[InlineData(false, QueryTrackingBehavior.NoTrackingWithIdentityResolution)]
[InlineData(true, QueryTrackingBehavior.NoTrackingWithIdentityResolution)]
public async Task Uninitialized_context_configuration_is_reset_properly(bool async, QueryTrackingBehavior? queryTrackingBehavior)
{
var serviceProvider = BuildServiceProvider<SecondContext>(b => UseQueryTrackingBehavior(b, queryTrackingBehavior));
var serviceScope = serviceProvider.CreateScope();
var ctx = serviceScope.ServiceProvider.GetRequiredService<SecondContext>();
@ -1062,11 +1222,17 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
=> _changeTracker_OnDetectedEntityChanges = true;
[ConditionalTheory]
[InlineData(false)]
[InlineData(true)]
public async Task Default_Context_configuration_is_reset(bool async)
{
var serviceProvider = BuildServiceProvider<DefaultOptionsPooledContext>();
[InlineData(false, null)]
[InlineData(true, null)]
[InlineData(false, QueryTrackingBehavior.TrackAll)]
[InlineData(true, QueryTrackingBehavior.TrackAll)]
[InlineData(false, QueryTrackingBehavior.NoTracking)]
[InlineData(true, QueryTrackingBehavior.NoTracking)]
[InlineData(false, QueryTrackingBehavior.NoTrackingWithIdentityResolution)]
[InlineData(true, QueryTrackingBehavior.NoTrackingWithIdentityResolution)]
public async Task Default_Context_configuration_is_reset(bool async, QueryTrackingBehavior? queryTrackingBehavior)
{
var serviceProvider = BuildServiceProvider<DefaultOptionsPooledContext>(b => UseQueryTrackingBehavior(b, queryTrackingBehavior));
var serviceScope = serviceProvider.CreateScope();
var scopedProvider = serviceScope.ServiceProvider;
@ -1092,7 +1258,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.True(context2!.ChangeTracker.AutoDetectChangesEnabled);
Assert.True(context2.ChangeTracker.LazyLoadingEnabled);
Assert.Equal(QueryTrackingBehavior.TrackAll, context2.ChangeTracker.QueryTrackingBehavior);
Assert.Equal(queryTrackingBehavior ?? QueryTrackingBehavior.TrackAll, context2.ChangeTracker.QueryTrackingBehavior);
Assert.Equal(CascadeTiming.Immediate, context2.ChangeTracker.CascadeDeleteTiming);
Assert.Equal(CascadeTiming.Immediate, context2.ChangeTracker.DeleteOrphansTiming);
Assert.Equal(AutoTransactionBehavior.WhenNeeded, context2.Database.AutoTransactionBehavior);
@ -1214,6 +1380,101 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.False(weakRef.IsAlive);
}
[ConditionalTheory] // Issue #25486
[InlineData(false, false, false)]
[InlineData(true, false, false)]
[InlineData(false, true, false)]
[InlineData(true, true, false)]
[InlineData(false, false, true)]
[InlineData(true, false, true)]
[InlineData(false, true, true)]
[InlineData(true, true, true)]
public async Task Service_properties_are_disposed(bool useInterface, bool async, bool load)
{
var serviceProvider = useInterface
? BuildServiceProvider<IPooledContext, PooledContext>()
: BuildServiceProvider<PooledContext>();
var serviceScope = serviceProvider.CreateScope();
var scopedProvider = serviceScope.ServiceProvider;
var context1 = useInterface
? (PooledContext)scopedProvider.GetService<IPooledContext>()
: scopedProvider.GetService<PooledContext>();
context1.ChangeTracker.LazyLoadingEnabled = true;
var entity = context1.Customers.First(c => c.CustomerId == "ALFKI");
var orderLoader = entity.LazyLoader;
if (load)
{
orderLoader.Load(entity, nameof(Customer.Orders));
Assert.True(orderLoader.IsLoaded(entity, nameof(Customer.Orders)));
}
Assert.Equal(load ? 7 : 1, context1.ChangeTracker.Entries().Count());
await Dispose(serviceScope, async);
if (load)
{
orderLoader.Load(entity, nameof(Customer.Orders));
Assert.True(orderLoader.IsLoaded(entity, nameof(Customer.Orders)));
orderLoader.SetLoaded(entity, nameof(Customer.Orders), loaded: false);
}
AssertDisposed(() => orderLoader.Load(entity, nameof(Customer.Orders)), "Customer", "Orders");
}
[ConditionalTheory] // Issue #25486
[InlineData(false, false, false)]
[InlineData(true, false, false)]
[InlineData(false, true, false)]
[InlineData(true, true, false)]
[InlineData(false, false, true)]
[InlineData(true, false, true)]
[InlineData(false, true, true)]
[InlineData(true, true, true)]
public async Task Service_properties_are_disposed_with_factory(bool async, bool withDependencyInjection, bool load)
{
var factory = BuildFactory<PooledContext>(withDependencyInjection);
var context1 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
context1.ChangeTracker.LazyLoadingEnabled = true;
var entity = context1.Customers.First(c => c.CustomerId == "ALFKI");
var orderLoader = entity.LazyLoader;
if (load)
{
orderLoader.Load(entity, nameof(Customer.Orders));
Assert.True(orderLoader.IsLoaded(entity, nameof(Customer.Orders)));
}
Assert.Equal(load ? 7 : 1, context1.ChangeTracker.Entries().Count());
await Dispose(context1, async);
if (load)
{
orderLoader.Load(entity, nameof(Customer.Orders));
Assert.True(orderLoader.IsLoaded(entity, nameof(Customer.Orders)));
orderLoader.SetLoaded(entity, nameof(Customer.Orders), loaded: false);
}
AssertDisposed(() => orderLoader.Load(entity, nameof(Customer.Orders)), "Customer", "Orders");
}
private static void AssertDisposed(Action testCode, string entityTypeName, string navigationName)
=> Assert.Equal(
CoreStrings.WarningAsErrorTemplate(
CoreEventId.LazyLoadOnDisposedContextWarning.ToString(),
CoreResources.LogLazyLoadOnDisposedContext(new TestLogger<TestLoggingDefinitions>())
.GenerateMessage(entityTypeName, navigationName),
"CoreEventId.LazyLoadOnDisposedContextWarning"),
Assert.Throws<InvalidOperationException>(
testCode).Message);
[ConditionalTheory]
[InlineData(false, false)]
[InlineData(true, false)]
@ -1381,7 +1642,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
{
var serviceProvider = useInterface
? BuildServiceProvider<IPooledContext, PooledContext>()
: BuildServiceProvider<PooledContext>();
: BuildServiceProvider<PooledContext>(o => o.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));
var serviceScope = serviceProvider.CreateScope();
var scopedProvider = serviceScope.ServiceProvider;
@ -1499,11 +1760,11 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
}
}
Assert.Equal(System.Data.ConnectionState.Open, connection1.State);
Assert.Equal(ConnectionState.Open, connection1.State);
await Dispose(serviceScope, async);
Assert.Equal(System.Data.ConnectionState.Closed, connection1.State);
Assert.Equal(ConnectionState.Closed, connection1.State);
serviceScope = serviceProvider.CreateScope();
scopedProvider = serviceScope.ServiceProvider;
@ -1514,7 +1775,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
var connection2 = context2.Database.GetDbConnection();
Assert.Same(connection1, connection2);
Assert.Equal(System.Data.ConnectionState.Closed, connection1.State);
Assert.Equal(ConnectionState.Closed, connection1.State);
await Dispose(serviceScope, async);
}
@ -1580,11 +1841,11 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
}
}
Assert.Equal(System.Data.ConnectionState.Open, connection.State);
Assert.Equal(ConnectionState.Open, connection.State);
await Dispose(serviceScope, async);
Assert.Equal(System.Data.ConnectionState.Open, connection.State);
Assert.Equal(ConnectionState.Open, connection.State);
serviceScope = serviceProvider.CreateScope();
scopedProvider = serviceScope.ServiceProvider;
@ -1594,7 +1855,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
Assert.Same(connection, context2.Database.GetDbConnection());
Assert.Equal(System.Data.ConnectionState.Open, connection.State);
Assert.Equal(ConnectionState.Open, connection.State);
await Dispose(serviceScope, async);
}
@ -1654,11 +1915,11 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
}
}
Assert.Equal(System.Data.ConnectionState.Open, connection1.State);
Assert.Equal(ConnectionState.Open, connection1.State);
await Dispose(context1, async);
Assert.Equal(System.Data.ConnectionState.Closed, connection1.State);
Assert.Equal(ConnectionState.Closed, connection1.State);
var context2 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
Assert.Same(context1, context2);
@ -1666,7 +1927,7 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
var connection2 = context2.Database.GetDbConnection();
Assert.Same(connection1, connection2);
Assert.Equal(System.Data.ConnectionState.Closed, connection1.State);
Assert.Equal(ConnectionState.Closed, connection1.State);
await Dispose(context2, async);
}
@ -1748,18 +2009,18 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
}
}
Assert.Equal(System.Data.ConnectionState.Open, connection.State);
Assert.Equal(ConnectionState.Open, connection.State);
await Dispose(context1, async);
Assert.Equal(System.Data.ConnectionState.Open, connection.State);
Assert.Equal(ConnectionState.Open, connection.State);
var context2 = async ? await factory.CreateDbContextAsync() : factory.CreateDbContext();
Assert.Same(context1, context2);
Assert.Same(connection, context2.Database.GetDbConnection());
Assert.Equal(System.Data.ConnectionState.Open, connection.State);
Assert.Equal(ConnectionState.Open, connection.State);
await Dispose(context2, async);
}
@ -1908,6 +2169,14 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
})));
}
private void UseQueryTrackingBehavior(DbContextOptionsBuilder optionsBuilder, QueryTrackingBehavior? queryTrackingBehavior)
{
if (queryTrackingBehavior.HasValue)
{
optionsBuilder.UseQueryTrackingBehavior(queryTrackingBehavior.Value);
}
}
private async Task Dispose(IDisposable disposable, bool async)
{
if (async)
@ -1920,12 +2189,10 @@ namespace EntityFrameworkCore.Jet.FunctionalTests
}
}
private readonly ITestOutputHelper _testOutputHelper = null;
private readonly ITestOutputHelper _testOutputHelper;
// ReSharper disable once UnusedParameter.Local
public DbContextPoolingTest(NorthwindQueryJetFixture<NoopModelCustomizer> fixture, ITestOutputHelper testOutputHelper)
{
//_testOutputHelper = testOutputHelper;
}
_testOutputHelper = testOutputHelper;
}
}

Loading…
Cancel
Save