diff --git a/Directory.Packages.props b/Directory.Packages.props
index 8f791b37..fd58cef0 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -28,7 +28,6 @@
-
@@ -38,6 +37,14 @@
+
+
+
+
+
+
+
+
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/Ardalis.Specification.EntityFramework6.Tests.csproj b/tests/Ardalis.Specification.EntityFramework6.Tests/Ardalis.Specification.EntityFramework6.Tests.csproj
index 899b5972..c80c20c6 100644
--- a/tests/Ardalis.Specification.EntityFramework6.Tests/Ardalis.Specification.EntityFramework6.Tests.csproj
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/Ardalis.Specification.EntityFramework6.Tests.csproj
@@ -7,11 +7,12 @@
-
-
-
-
-
+
+
+
+
+
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Address.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Address.cs
new file mode 100644
index 00000000..e644cac6
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Address.cs
@@ -0,0 +1,11 @@
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace Tests.FixtureNew;
+
+public record Address
+{
+ public int Id { get; set; }
+ public string? Street { get; set; }
+
+ public Store Store { get; set; } = default!;
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Company.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Company.cs
new file mode 100644
index 00000000..b78353b0
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Company.cs
@@ -0,0 +1,14 @@
+using System.ComponentModel.DataAnnotations.Schema;
+
+namespace Tests.FixtureNew;
+
+public record Company
+{
+ public int Id { get; set; }
+ public required string Name { get; set; }
+
+ public int CountryId { get; set; }
+ public Country Country { get; set; } = default!;
+
+ public List Stores { get; set; } = [];
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Country.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Country.cs
new file mode 100644
index 00000000..c445a3b2
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Country.cs
@@ -0,0 +1,9 @@
+namespace Tests.FixtureNew;
+
+public record Country
+{
+ public int Id { get; set; }
+ public int No { get; set; }
+ public string? Name { get; set; }
+ public bool IsDeleted { get; set; }
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Product.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Product.cs
new file mode 100644
index 00000000..f256fa50
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Product.cs
@@ -0,0 +1,12 @@
+namespace Tests.FixtureNew;
+
+public record Product
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+
+ public int StoreId { get; set; }
+ public Store Store { get; set; } = default!;
+
+ public List? Images { get; set; }
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/ProductImage.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/ProductImage.cs
new file mode 100644
index 00000000..479a8e6c
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/ProductImage.cs
@@ -0,0 +1,9 @@
+namespace Tests.FixtureNew;
+
+public record ProductImage
+{
+ public int Id { get; set; }
+ public string? ImageUrl { get; set; }
+ public int ProductId { get; set; }
+ public Product Product { get; set; } = default!;
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Store.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Store.cs
new file mode 100644
index 00000000..5e46502a
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Data/Store.cs
@@ -0,0 +1,15 @@
+namespace Tests.FixtureNew;
+
+public record Store
+{
+ public int Id { get; set; }
+ public string? Name { get; set; }
+ public string? City { get; set; }
+
+ public int CompanyId { get; set; }
+ public Company Company { get; set; } = default!;
+
+ public Address Address { get; set; } = default!;
+
+ public List Products { get; set; } = [];
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/IntegrationTest.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/IntegrationTest.cs
new file mode 100644
index 00000000..e669deb8
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/IntegrationTest.cs
@@ -0,0 +1,50 @@
+using System.Collections;
+
+namespace Tests.FixtureNew;
+
+public class IntegrationTest : IAsyncLifetime
+{
+ protected TestDbContext DbContext { get; private set; } = default!;
+ private readonly TestFactory _testFactory;
+
+ public IntegrationTest(TestFactory testFactory)
+ {
+ _testFactory = testFactory;
+ }
+
+ public Task InitializeAsync()
+ {
+ DbContext = new TestDbContext(_testFactory.ConnectionString);
+ return Task.CompletedTask;
+ }
+
+ public async Task DisposeAsync()
+ {
+ DbContext.Dispose();
+ await _testFactory.ResetDatabase();
+ }
+
+ public async Task SeedAsync(TEntity entity) where TEntity : class
+ {
+ using var dbContext = new TestDbContext(_testFactory.ConnectionString);
+ dbContext.Set().Add(entity);
+ await dbContext.SaveChangesAsync();
+ }
+
+ public async Task SeedRangeAsync(TEntity[] entities) where TEntity : class
+ {
+ using var dbContext = new TestDbContext(_testFactory.ConnectionString);
+ dbContext.Set().AddRange(entities);
+ await dbContext.SaveChangesAsync();
+ }
+
+ public async Task SeedRangeAsync(IEnumerable entities)
+ {
+ using var dbContext = new TestDbContext(_testFactory.ConnectionString);
+ foreach (var entity in entities)
+ {
+ dbContext.Set(entity.GetType()).Add(entity);
+ }
+ await dbContext.SaveChangesAsync();
+ }
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Repository.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Repository.cs
new file mode 100644
index 00000000..8f01119c
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/Repository.cs
@@ -0,0 +1,5 @@
+namespace Tests.FixtureNew;
+
+public class Repository(TestDbContext context) : RepositoryBase(context) where T : class
+{
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/SharedCollection.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/SharedCollection.cs
new file mode 100644
index 00000000..ae75ad31
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/SharedCollection.cs
@@ -0,0 +1,6 @@
+namespace Tests.FixtureNew;
+
+[CollectionDefinition("SharedCollection")]
+public class SharedCollection : ICollectionFixture
+{
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/TestDbContext.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/TestDbContext.cs
new file mode 100644
index 00000000..0c9aef4d
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/TestDbContext.cs
@@ -0,0 +1,31 @@
+using System.Data.Entity;
+
+namespace Tests.FixtureNew;
+
+public class TestDbContext : DbContext
+{
+ public TestDbContext(string connectionString) : base(connectionString)
+ {
+ }
+
+ public DbSet Countries => Set();
+ public DbSet Companies => Set();
+ public DbSet Stores => Set();
+ public DbSet Addresses => Set();
+ public DbSet Products => Set();
+
+ protected override void OnModelCreating(DbModelBuilder modelBuilder)
+ {
+ // Store-Address one-to-one (Address has StoreId FK)
+ modelBuilder.Entity()
+ .HasOptional(s => s.Address)
+ .WithRequired(a => a.Store)
+ .Map(m => m.MapKey("StoreId"));
+
+ // Country-Company one-to-many (Company has CountryId FK)
+ modelBuilder.Entity()
+ .HasRequired(co => co.Country)
+ .WithMany()
+ .HasForeignKey(co => co.CountryId);
+ }
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/TestFactory.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/TestFactory.cs
new file mode 100644
index 00000000..196e6dc9
--- /dev/null
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/FixtureNew/TestFactory.cs
@@ -0,0 +1,89 @@
+using MartinCostello.SqlLocalDb;
+using Testcontainers.MsSql;
+using Respawn;
+
+namespace Tests.FixtureNew;
+
+public class TestFactory : IAsyncLifetime
+{
+ // Flag to force using Docker SQL Server. Update it manually if you want to avoid localDb locally.
+ private const bool FORCE_DOCKER = false;
+
+ private string _connectionString = default!;
+ private MsSqlContainer? _dbContainer = null;
+
+ public string ConnectionString => _connectionString;
+ public TestDbContext DbContext => new TestDbContext(_connectionString);
+
+#if NET9_0_OR_GREATER
+ private Respawner _respawner = default!;
+ public async Task ResetDatabase() => await _respawner.ResetAsync(_connectionString);
+#elif NET472
+ private Checkpoint _respawner = default!;
+ public Task ResetDatabase() => _respawner.Reset(_connectionString);
+#endif
+
+ public async Task InitializeAsync()
+ {
+ using (var localDB = new SqlLocalDbApi())
+ {
+ if (FORCE_DOCKER || !localDB.IsLocalDBInstalled())
+ {
+ _dbContainer = CreateContainer();
+ await _dbContainer.StartAsync();
+ _connectionString = _dbContainer.GetConnectionString();
+ }
+ else
+ {
+#if NET9_0_OR_GREATER
+ _connectionString = "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SpecificationTestsDB_EF6_NET9;Integrated Security=SSPI;TrustServerCertificate=True;";
+#elif NET472
+
+ _connectionString = "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SpecificationTestsDB_EF6_NETFFX;Integrated Security=SSPI;TrustServerCertificate=True;";
+#endif
+ }
+ }
+
+ Console.WriteLine($"Connection string: {_connectionString}");
+
+ using (var dbContext = new TestDbContext(_connectionString))
+ {
+ //dbContext.Database.Delete();
+ dbContext.Database.CreateIfNotExists();
+ }
+
+#if NET9_0_OR_GREATER
+ _respawner = await Respawner.CreateAsync(_connectionString, new RespawnerOptions
+ {
+ DbAdapter = DbAdapter.SqlServer,
+ SchemasToInclude = new[] { "dbo" },
+ });
+ await ResetDatabase();
+#elif NET472
+ _respawner = new Checkpoint
+ {
+ DbAdapter = DbAdapter.SqlServer,
+ SchemasToInclude = new[] { "dbo" },
+ };
+ await ResetDatabase();
+#endif
+ }
+
+ public async Task DisposeAsync()
+ {
+ if (_dbContainer is not null)
+ {
+ await _dbContainer.StopAsync();
+ }
+ else
+ {
+ //using var dbContext = new TestDbContext(_connectionString);
+ //dbContext.Database.Delete();
+ }
+ }
+
+ private static MsSqlContainer CreateContainer() => new MsSqlBuilder()
+ .WithImage("mcr.microsoft.com/mssql/server:2022-latest")
+ .WithPassword("P@ssW0rd!")
+ .Build();
+}
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/GlobalUsings.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/GlobalUsings.cs
index b0608534..c1450d15 100644
--- a/tests/Ardalis.Specification.EntityFramework6.Tests/GlobalUsings.cs
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/GlobalUsings.cs
@@ -5,5 +5,4 @@
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
-global using Tests.Fixture;
global using Xunit;
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_AnyAsync.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_AnyAsync.cs
index 12840eeb..1214976e 100644
--- a/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_AnyAsync.cs
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_AnyAsync.cs
@@ -1,4 +1,6 @@
-namespace Tests;
+using Tests.Fixture;
+
+namespace Tests;
[Collection("ReadCollection")]
public class RepositoryOfT_AnyAsync
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_DeleteRangeAsync.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_DeleteRangeAsync.cs
index 4b1f1359..dfc262ca 100644
--- a/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_DeleteRangeAsync.cs
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_DeleteRangeAsync.cs
@@ -1,4 +1,6 @@
-namespace Tests;
+using Tests.Fixture;
+
+namespace Tests;
[Collection("WriteCollection")]
public class RepositoryOfT_DeleteRangeAsync
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_GetById.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_GetById.cs
index 14a8a9ef..a1a87acb 100644
--- a/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_GetById.cs
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_GetById.cs
@@ -1,4 +1,6 @@
-namespace Tests;
+using Tests.Fixture;
+
+namespace Tests;
[Collection("ReadCollection")]
public class RepositoryOfT_GetById
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_GetBySpec.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_GetBySpec.cs
index 8b2f855f..66656bb7 100644
--- a/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_GetBySpec.cs
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_GetBySpec.cs
@@ -1,4 +1,5 @@
-using System.Data.Entity;
+using Tests.Fixture;
+using System.Data.Entity;
namespace Tests;
diff --git a/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_ListAsync.cs b/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_ListAsync.cs
index 8b255ac8..6a8a797f 100644
--- a/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_ListAsync.cs
+++ b/tests/Ardalis.Specification.EntityFramework6.Tests/RepositoryOfT_ListAsync.cs
@@ -1,4 +1,6 @@
-namespace Tests;
+using Tests.Fixture;
+
+namespace Tests;
[Collection("ReadCollection")]
public class RepositoryOfT_ListAsync
diff --git a/tests/Ardalis.Specification.EntityFrameworkCore.Tests/Fixture/TestFactory.cs b/tests/Ardalis.Specification.EntityFrameworkCore.Tests/Fixture/TestFactory.cs
index 5e8b2abb..e8a25279 100644
--- a/tests/Ardalis.Specification.EntityFrameworkCore.Tests/Fixture/TestFactory.cs
+++ b/tests/Ardalis.Specification.EntityFrameworkCore.Tests/Fixture/TestFactory.cs
@@ -29,7 +29,7 @@ public async Task InitializeAsync()
}
else
{
- _connectionString = "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SpecificationEFCoreTestsDB;Integrated Security=SSPI;TrustServerCertificate=True;";
+ _connectionString = "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=SpecificationTestsDB_EFCore;Integrated Security=SSPI;TrustServerCertificate=True;";
}
}
@@ -70,7 +70,7 @@ public async Task DisposeAsync()
private static MsSqlContainer CreateContainer() => new MsSqlBuilder()
.WithImage("mcr.microsoft.com/mssql/server:2022-latest")
- .WithName("SpecificationEFCoreTestsDB")
+ .WithName("SpecificationTestsDB_EFCore")
.WithPassword("P@ssW0rd!")
.Build();
}