diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6a4770100e..9f44f8bcdc 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -17,6 +17,9 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
+ - name: Install SQL Local DB
+ run: ./Setup.ps1
+ shell: pwsh
- name: Build and Test
run: ./Build.ps1
shell: pwsh
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 4aa4761ef3..8f864af155 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -14,6 +14,9 @@ jobs:
uses: actions/checkout@v2
with:
fetch-depth: 0
+ - name: Install SQL Local DB
+ run: ./Setup.ps1
+ shell: pwsh
- name: Build and Test
run: ./Build.ps1
shell: pwsh
diff --git a/AutoMapper.sln b/AutoMapper.sln
index e57553e109..194e366c0c 100644
--- a/AutoMapper.sln
+++ b/AutoMapper.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 16
-VisualStudioVersion = 16.0.29215.179
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.32002.185
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0691ABF2-B3C7-43BF-9862-2D8D1299CE58}"
ProjectSection(SolutionItems) = preProject
@@ -14,6 +14,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
Push.ps1 = Push.ps1
README.md = README.md
.github\workflows\release.yml = .github\workflows\release.yml
+ Setup.ps1 = Setup.ps1
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Benchmark", "src\Benchmark\Benchmark.csproj", "{B8051389-CB47-46FB-B234-9D49506704AA}"
diff --git a/Setup.ps1 b/Setup.ps1
new file mode 100644
index 0000000000..a20035ad42
--- /dev/null
+++ b/Setup.ps1
@@ -0,0 +1,32 @@
+# Taken from psake https://github.com/psake/psake
+
+<#
+.SYNOPSIS
+ This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode
+ to see if an error occcured. If an error is detected then an exception is thrown.
+ This function allows you to run command-line programs without having to
+ explicitly check the $lastexitcode variable.
+.EXAMPLE
+ exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
+#>
+function Exec
+{
+ [CmdletBinding()]
+ param(
+ [Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
+ [Parameter(Position=1,Mandatory=0)][string]$errorMessage = ($msgs.error_bad_command -f $cmd)
+ )
+ & $cmd
+ if ($lastexitcode -ne 0) {
+ throw ("Exec: " + $errorMessage)
+ }
+}
+
+Write-Host "Downloading"
+Import-Module BitsTransfer
+Start-BitsTransfer -Source https://download.microsoft.com/download/7/c/1/7c14e92e-bdcb-4f89-b7cf-93543e7112d1/SqlLocalDB.msi -Destination SqlLocalDB.msi
+Write-Host "Installing"
+Start-Process -FilePath "SqlLocalDB.msi" -Wait -ArgumentList "/qn", "/norestart", "/l*v SqlLocalDBInstall.log", "IACCEPTSQLLOCALDBLICENSETERMS=YES";
+Write-Host "Checking"
+sqlcmd -l 60 -S "(localdb)\MSSQLLocalDB" -Q "SELECT @@VERSION;"
+
diff --git a/src/IntegrationTests/App.config b/src/IntegrationTests/App.config
deleted file mode 100644
index b63cdc70ad..0000000000
--- a/src/IntegrationTests/App.config
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/IntegrationTests/AutoMapper.IntegrationTests.csproj b/src/IntegrationTests/AutoMapper.IntegrationTests.csproj
index da830e1022..89294efffa 100644
--- a/src/IntegrationTests/AutoMapper.IntegrationTests.csproj
+++ b/src/IntegrationTests/AutoMapper.IntegrationTests.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/src/IntegrationTests/BuiltInTypes/ByteArray.cs b/src/IntegrationTests/BuiltInTypes/ByteArray.cs
index 8c0c8c6708..1b54202cef 100644
--- a/src/IntegrationTests/BuiltInTypes/ByteArray.cs
+++ b/src/IntegrationTests/BuiltInTypes/ByteArray.cs
@@ -1,75 +1,76 @@
using System.ComponentModel.DataAnnotations;
-using System.Data.Entity;
using System.Linq;
+using System.Threading.Tasks;
+using AutoMapper.UnitTests;
+using Microsoft.EntityFrameworkCore;
using Shouldly;
using Xunit;
-namespace AutoMapper.IntegrationTests
+namespace AutoMapper.IntegrationTests.BuiltInTypes;
+
+public class ByteArrayColumns : AutoMapperSpecBase, IAsyncLifetime
{
- using UnitTests;
- using QueryableExtensions;
-
- public class ByteArrayColumns : AutoMapperSpecBase
+ public class Customer
{
- public class Customer
- {
- [Key]
- public int Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
-
- public byte[] RowVersion { get; set; }
- }
+ [Key]
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
- public class CustomerViewModel
- {
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public byte[] RowVersion { get; set; }
- }
+ public byte[] RowVersion { get; set; }
+ }
- public class Context : DbContext
- {
- public Context()
- {
- Database.SetInitializer(new DatabaseInitializer());
- }
+ public class CustomerViewModel
+ {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public byte[] RowVersion { get; set; }
+ }
- public DbSet Customers { get; set; }
- }
+ public class Context : LocalDbContext
+ {
+ public DbSet Customers { get; set; }
+ }
- public class DatabaseInitializer : CreateDatabaseIfNotExists
+ public class DatabaseInitializer : CreateDatabaseIfNotExists
+ {
+ protected override void Seed(Context context)
{
- protected override void Seed(Context context)
+ context.Customers.Add(new Customer
{
- context.Customers.Add(new Customer
- {
- Id = 1,
- FirstName = "Bob",
- LastName = "Smith",
- RowVersion = new byte[] { 1, 2, 3 }
- });
+ FirstName = "Bob",
+ LastName = "Smith",
+ RowVersion = new byte[] { 1, 2, 3 }
+ });
- base.Seed(context);
- }
+ base.Seed(context);
}
+ }
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection();
- });
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection();
+ });
- [Fact]
- public void Can_map_with_projection()
+ [Fact]
+ public void Can_map_with_projection()
+ {
+ using (var context = new Context())
{
- using (var context = new Context())
+ var customerVms = ProjectTo(context.Customers).ToList();
+ customerVms.ForEach(x =>
{
- var customerVms = ProjectTo(context.Customers).ToList();
- customerVms.ForEach(x =>
- {
- x.RowVersion.SequenceEqual(new byte[] { 1, 2, 3 }).ShouldBeTrue();
- });
- }
+ x.RowVersion.SequenceEqual(new byte[] { 1, 2, 3 }).ShouldBeTrue();
+ });
}
}
+
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
+
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
}
\ No newline at end of file
diff --git a/src/IntegrationTests/BuiltInTypes/DateTimeToNullableDateTime.cs b/src/IntegrationTests/BuiltInTypes/DateTimeToNullableDateTime.cs
index 69988a2e63..8eef1e3df3 100644
--- a/src/IntegrationTests/BuiltInTypes/DateTimeToNullableDateTime.cs
+++ b/src/IntegrationTests/BuiltInTypes/DateTimeToNullableDateTime.cs
@@ -1,46 +1,57 @@
-using Shouldly;
-using System;
-using System.Data.Entity;
+using System;
using System.Linq;
+using System.Threading.Tasks;
+using AutoMapper.UnitTests;
+using Microsoft.EntityFrameworkCore;
+using Shouldly;
using Xunit;
-namespace AutoMapper.UnitTests.Projection
+namespace AutoMapper.IntegrationTests.BuiltInTypes;
+
+public class DateTimeToNullableDateTime : AutoMapperSpecBase, IAsyncLifetime
{
- public class DateTimeToNullableDateTime : AutoMapperSpecBase
+ public class Parent
{
- public class Parent
- {
- public int Id { get; set; }
- public int Value { get; set; }
+ public int Id { get; set; }
+ public int Value { get; set; }
- }
- public class ParentDto
- {
- public int? Value { get; set; }
- public DateTime? Date { get; set; }
- }
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- cfg.CreateProjection().ForMember(dto => dto.Date, opt => opt.MapFrom(src => DateTime.MaxValue)));
- public class TestContext : DbContext
- {
- public TestContext(): base() => Database.SetInitializer(new DatabaseInitializer());
- public DbSet Parents { get; set; }
- }
- public class DatabaseInitializer : DropCreateDatabaseAlways
+ }
+ public class ParentDto
+ {
+ public int? Value { get; set; }
+ public DateTime? Date { get; set; }
+ }
+
+ private readonly DateTime _expected = new(2000, 1, 1);
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ cfg.CreateProjection().ForMember(dto => dto.Date, opt => opt.MapFrom(src => _expected)));
+ public class TestContext : LocalDbContext
+ {
+ public DbSet Parents { get; set; }
+ }
+ public class DatabaseInitializer : DropCreateDatabaseAlways
+ {
+ protected override void Seed(TestContext testContext)
{
- protected override void Seed(TestContext testContext)
- {
- testContext.Parents.Add(new Parent{ Value = 5 });
- base.Seed(testContext);
- }
+ testContext.Parents.Add(new Parent{ Value = 5 });
+ base.Seed(testContext);
}
- [Fact]
- public void Should_not_fail()
+ }
+ [Fact]
+ public void Should_not_fail()
+ {
+ using (var context = new TestContext())
{
- using (var context = new TestContext())
- {
- ProjectTo(context.Parents).Single().Date.ShouldBe(DateTime.MaxValue);
- }
+ ProjectTo(context.Parents).Single().Date.ShouldBe(_expected);
}
}
+
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
+
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
}
\ No newline at end of file
diff --git a/src/IntegrationTests/BuiltInTypes/Enums.cs b/src/IntegrationTests/BuiltInTypes/Enums.cs
index d1b7a9ce0b..b1341aebf3 100644
--- a/src/IntegrationTests/BuiltInTypes/Enums.cs
+++ b/src/IntegrationTests/BuiltInTypes/Enums.cs
@@ -1,126 +1,148 @@
-using System.ComponentModel.DataAnnotations;
-using System.Data.Entity;
+using System;
using System.Linq;
+using System.Threading.Tasks;
+using AutoMapper.UnitTests;
+using Microsoft.EntityFrameworkCore;
using Shouldly;
using Xunit;
-namespace AutoMapper.IntegrationTests
-{
- using System;
- using UnitTests;
+namespace AutoMapper.IntegrationTests.BuiltInTypes;
- public class EnumToUnderlyingType : AutoMapperSpecBase
+public class EnumToUnderlyingType : AutoMapperSpecBase, IAsyncLifetime
+{
+ public class Customer
{
- public class Customer
- {
- public int Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public ConsoleColor ConsoleColor { get; set; }
- }
- public class CustomerViewModel
- {
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public int ConsoleColor { get; set; }
- }
- public class Context : DbContext
- {
- public Context() => Database.SetInitializer(new DatabaseInitializer());
- public DbSet Customers { get; set; }
- }
- public class DatabaseInitializer : CreateDatabaseIfNotExists
- {
- protected override void Seed(Context context)
- {
- context.Customers.Add(new Customer { Id = 1, FirstName = "Bob", LastName = "Smith", ConsoleColor = ConsoleColor.Yellow });
- base.Seed(context);
- }
- }
- protected override MapperConfiguration CreateConfiguration() => new(cfg => cfg.CreateProjection());
- [Fact]
- public void Can_map_with_projection()
- {
- using (var context = new Context())
- {
- ProjectTo(context.Customers).First().ConsoleColor.ShouldBe((int)ConsoleColor.Yellow);
- }
- }
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public ConsoleColor ConsoleColor { get; set; }
}
- public class UnderlyingTypeToEnum : AutoMapperSpecBase
+ public class CustomerViewModel
{
- public class Customer
- {
- public int Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public int ConsoleColor { get; set; }
- }
- public class CustomerViewModel
- {
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public ConsoleColor ConsoleColor { get; set; }
- }
- public class Context : DbContext
- {
- public Context() => Database.SetInitializer(new DatabaseInitializer());
- public DbSet Customers { get; set; }
- }
- public class DatabaseInitializer : CreateDatabaseIfNotExists
- {
- protected override void Seed(Context context)
- {
- context.Customers.Add(new Customer { Id = 1, FirstName = "Bob", LastName = "Smith", ConsoleColor = (int)ConsoleColor.Yellow });
- base.Seed(context);
- }
- }
- protected override MapperConfiguration CreateConfiguration() => new(cfg => cfg.CreateProjection());
- [Fact]
- public void Can_map_with_projection()
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public int ConsoleColor { get; set; }
+ }
+ public class Context : LocalDbContext
+ {
+ public DbSet Customers { get; set; }
+ }
+ public class DatabaseInitializer : CreateDatabaseIfNotExists
+ {
+ protected override void Seed(Context context)
{
- using (var context = new Context())
- {
- ProjectTo(context.Customers).First().ConsoleColor.ShouldBe(ConsoleColor.Yellow);
- }
+ context.Customers.Add(new Customer { FirstName = "Bob", LastName = "Smith", ConsoleColor = ConsoleColor.Yellow });
+ base.Seed(context);
}
}
- public class EnumToEnum : AutoMapperSpecBase
+ protected override MapperConfiguration CreateConfiguration() => new(cfg => cfg.CreateProjection());
+ [Fact]
+ public void Can_map_with_projection()
{
- public class Customer
+ using (var context = new Context())
{
- public int Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public DayOfWeek ConsoleColor { get; set; }
+ ProjectTo(context.Customers).First().ConsoleColor.ShouldBe((int)ConsoleColor.Yellow);
}
- public class CustomerViewModel
+ }
+
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
+
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
+}
+public class UnderlyingTypeToEnum : AutoMapperSpecBase, IAsyncLifetime
+{
+ public class Customer
+ {
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public int ConsoleColor { get; set; }
+ }
+ public class CustomerViewModel
+ {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public ConsoleColor ConsoleColor { get; set; }
+ }
+ public class Context : LocalDbContext
+ {
+ public DbSet Customers { get; set; }
+ }
+ public class DatabaseInitializer : CreateDatabaseIfNotExists
+ {
+ protected override void Seed(Context context)
{
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public ConsoleColor ConsoleColor { get; set; }
+ context.Customers.Add(new Customer { FirstName = "Bob", LastName = "Smith", ConsoleColor = (int)ConsoleColor.Yellow });
+ base.Seed(context);
}
- public class Context : DbContext
+ }
+ protected override MapperConfiguration CreateConfiguration() => new(cfg => cfg.CreateProjection());
+ [Fact]
+ public void Can_map_with_projection()
+ {
+ using (var context = new Context())
{
- public Context() => Database.SetInitializer(new DatabaseInitializer());
- public DbSet Customers { get; set; }
+ ProjectTo(context.Customers).First().ConsoleColor.ShouldBe(ConsoleColor.Yellow);
}
- public class DatabaseInitializer : CreateDatabaseIfNotExists
+ }
+
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
+
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
+}
+public class EnumToEnum : AutoMapperSpecBase, IAsyncLifetime
+{
+ public class Customer
+ {
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public DayOfWeek ConsoleColor { get; set; }
+ }
+ public class CustomerViewModel
+ {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public ConsoleColor ConsoleColor { get; set; }
+ }
+ public class Context : LocalDbContext
+ {
+ public DbSet Customers { get; set; }
+ }
+ public class DatabaseInitializer : CreateDatabaseIfNotExists
+ {
+ protected override void Seed(Context context)
{
- protected override void Seed(Context context)
- {
- context.Customers.Add(new Customer { Id = 1, FirstName = "Bob", LastName = "Smith", ConsoleColor = DayOfWeek.Saturday });
- base.Seed(context);
- }
+ context.Customers.Add(new Customer { FirstName = "Bob", LastName = "Smith", ConsoleColor = DayOfWeek.Saturday });
+ base.Seed(context);
}
- protected override MapperConfiguration CreateConfiguration() => new(cfg => cfg.CreateProjection());
- [Fact]
- public void Can_map_with_projection()
+ }
+ protected override MapperConfiguration CreateConfiguration() => new(cfg => cfg.CreateProjection());
+ [Fact]
+ public void Can_map_with_projection()
+ {
+ using (var context = new Context())
{
- using (var context = new Context())
- {
- ProjectTo(context.Customers).First().ConsoleColor.ShouldBe(ConsoleColor.DarkYellow);
- }
+ ProjectTo(context.Customers).First().ConsoleColor.ShouldBe(ConsoleColor.DarkYellow);
}
}
+
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
+
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
}
\ No newline at end of file
diff --git a/src/IntegrationTests/BuiltInTypes/NullableToNonNullable.cs b/src/IntegrationTests/BuiltInTypes/NullableToNonNullable.cs
index fe8a8dc96d..0a87132917 100644
--- a/src/IntegrationTests/BuiltInTypes/NullableToNonNullable.cs
+++ b/src/IntegrationTests/BuiltInTypes/NullableToNonNullable.cs
@@ -1,131 +1,135 @@
using System.ComponentModel.DataAnnotations;
-using System.Data.Entity;
using System.Linq;
+using System.Threading.Tasks;
+using AutoMapper.UnitTests;
+using Microsoft.EntityFrameworkCore;
using Shouldly;
using Xunit;
-namespace AutoMapper.IntegrationTests
+namespace AutoMapper.IntegrationTests.BuiltInTypes;
+
+public class NullableLongToLong : AutoMapperSpecBase, IAsyncLifetime
{
- using UnitTests;
- using QueryableExtensions;
-
- public class NullableLongToLong : AutoMapperSpecBase
+ public class Customer
{
- public class Customer
- {
- [Key]
- public long? Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- }
+ [Key]
+ public long? Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ }
- public class CustomerViewModel
- {
- public long Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- }
+ public class CustomerViewModel
+ {
+ public long Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ }
+
+ public class Context : LocalDbContext
+ {
+ public DbSet Customers { get; set; }
+ }
- public class Context : DbContext
+ public class DatabaseInitializer : CreateDatabaseIfNotExists
+ {
+ protected override void Seed(Context context)
{
- public Context()
+ context.Customers.Add(new Customer
{
- Database.SetInitializer(new DatabaseInitializer());
- }
+ FirstName = "Bob",
+ LastName = "Smith",
+ });
- public DbSet Customers { get; set; }
+ base.Seed(context);
}
+ }
+
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection();
+ });
- public class DatabaseInitializer : CreateDatabaseIfNotExists
+ [Fact]
+ public void Can_map_with_projection()
+ {
+ using (var context = new Context())
{
- protected override void Seed(Context context)
- {
- context.Customers.Add(new Customer
- {
- Id = 1,
- FirstName = "Bob",
- LastName = "Smith",
- });
-
- base.Seed(context);
- }
+ var model = ProjectTo(context.Customers).Single();
+ model.Id.ShouldBe(1);
+ model.FirstName.ShouldBe("Bob");
+ model.LastName.ShouldBe("Smith");
}
+ }
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection();
- });
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
- [Fact]
- public void Can_map_with_projection()
- {
- using (var context = new Context())
- {
- var model = ProjectTo(context.Customers).Single();
- model.Id.ShouldBe(1);
- model.FirstName.ShouldBe("Bob");
- model.LastName.ShouldBe("Smith");
- }
- }
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
+}
+
+public class NullableIntToLong : AutoMapperSpecBase, IAsyncLifetime
+{
+ public class Customer
+ {
+ [Key]
+ public int? Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
}
- public class NullableIntToLong : AutoMapperSpecBase
+ public class CustomerViewModel
{
- public class Customer
- {
- [Key]
- public int? Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- }
+ public long Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ }
- public class CustomerViewModel
- {
- public long Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- }
+ public class Context : LocalDbContext
+ {
+ public DbSet Customers { get; set; }
+ }
- public class Context : DbContext
+ public class DatabaseInitializer : CreateDatabaseIfNotExists
+ {
+ protected override void Seed(Context context)
{
- public Context()
+ context.Customers.Add(new Customer
{
- Database.SetInitializer(new DatabaseInitializer());
- }
+ FirstName = "Bob",
+ LastName = "Smith",
+ });
- public DbSet Customers { get; set; }
+ base.Seed(context);
}
+ }
+
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection();
+ });
- public class DatabaseInitializer : CreateDatabaseIfNotExists
+ [Fact]
+ public void Can_map_with_projection()
+ {
+ using(var context = new Context())
{
- protected override void Seed(Context context)
- {
- context.Customers.Add(new Customer
- {
- Id = 1,
- FirstName = "Bob",
- LastName = "Smith",
- });
-
- base.Seed(context);
- }
+ var model = ProjectTo(context.Customers).Single();
+ model.Id.ShouldBe(1);
+ model.FirstName.ShouldBe("Bob");
+ model.LastName.ShouldBe("Smith");
}
+ }
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection();
- });
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
- [Fact]
- public void Can_map_with_projection()
- {
- using(var context = new Context())
- {
- var model = ProjectTo(context.Customers).Single();
- model.Id.ShouldBe(1);
- model.FirstName.ShouldBe("Bob");
- model.LastName.ShouldBe("Smith");
- }
- }
+ await initializer.Migrate();
}
+
+ public Task DisposeAsync() => Task.CompletedTask;
}
\ No newline at end of file
diff --git a/src/IntegrationTests/BuiltInTypes/ProjectEnumerableOfIntToList.cs b/src/IntegrationTests/BuiltInTypes/ProjectEnumerableOfIntToList.cs
index c1c273a453..0bbe59fef9 100644
--- a/src/IntegrationTests/BuiltInTypes/ProjectEnumerableOfIntToList.cs
+++ b/src/IntegrationTests/BuiltInTypes/ProjectEnumerableOfIntToList.cs
@@ -1,77 +1,79 @@
-using System.ComponentModel.DataAnnotations;
-using System.Data.Entity;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
using System.Linq;
+using System.Threading.Tasks;
+using AutoMapper.UnitTests;
+using Microsoft.EntityFrameworkCore;
using Shouldly;
using Xunit;
-namespace AutoMapper.IntegrationTests
+namespace AutoMapper.IntegrationTests.BuiltInTypes;
+
+public class ProjectEnumerableOfIntToList : AutoMapperSpecBase, IAsyncLifetime
{
- using UnitTests;
- using QueryableExtensions;
- using System.Collections.Generic;
+ public class Customer
+ {
+ [Key]
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public List- Items { get; set; }
+ }
- public class ProjectEnumerableOfIntToList : AutoMapperSpecBase
+ public class Item
{
- public class Customer
- {
- [Key]
- public int Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public List
- Items { get; set; }
- }
+ public int Id { get; set; }
+ }
- public class Item
- {
- public int Id { get; set; }
- }
+ public class CustomerViewModel
+ {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public List ItemsIds { get; set; }
+ }
- public class CustomerViewModel
- {
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public List ItemsIds { get; set; }
- }
+ public class Context : LocalDbContext
+ {
+ public DbSet Customers { get; set; }
+ public DbSet
- Items { get; set; }
+ }
- public class Context : DbContext
+ public class DatabaseInitializer : DropCreateDatabaseAlways
+ {
+ protected override void Seed(Context context)
{
- public Context()
+ context.Customers.Add(new Customer
{
- Database.SetInitializer(new DatabaseInitializer());
- }
+ FirstName = "Bob",
+ LastName = "Smith",
+ Items = new List
- (new[] { new Item(), new Item(), new Item()})
+ });
- public DbSet Customers { get; set; }
+ base.Seed(context);
}
+ }
- public class DatabaseInitializer : DropCreateDatabaseAlways
- {
- protected override void Seed(Context context)
- {
- context.Customers.Add(new Customer
- {
- Id = 1,
- FirstName = "Bob",
- LastName = "Smith",
- Items = new List
- (new[] { new Item { Id = 1 }, new Item { Id = 3 }, new Item { Id = 3 } })
- });
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection().ForMember(d=>d.ItemsIds, o=>o.MapFrom(s=>s.Items.Select(i=>i.Id)));
+ });
- base.Seed(context);
- }
+ [Fact]
+ public void Can_map_with_projection()
+ {
+ using(var context = new Context())
+ {
+ var customer = ProjectTo(context.Customers).Single();
+ customer.ItemsIds.SequenceEqual(new int[] { 1, 2, 3 }).ShouldBeTrue();
}
+ }
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection().ForMember(d=>d.ItemsIds, o=>o.MapFrom(s=>s.Items.Select(i=>i.Id)));
- });
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
- [Fact]
- public void Can_map_with_projection()
- {
- using(var context = new Context())
- {
- var customer = ProjectTo(context.Customers).Single();
- customer.ItemsIds.SequenceEqual(new int[] { 1, 2, 3 }).ShouldBeTrue();
- }
- }
+ await initializer.Migrate();
}
+
+ public Task DisposeAsync() => Task.CompletedTask;
}
\ No newline at end of file
diff --git a/src/IntegrationTests/BuiltInTypes/ProjectUsing.cs b/src/IntegrationTests/BuiltInTypes/ProjectUsing.cs
index 8cd1e09bcd..4c19e6a3c8 100644
--- a/src/IntegrationTests/BuiltInTypes/ProjectUsing.cs
+++ b/src/IntegrationTests/BuiltInTypes/ProjectUsing.cs
@@ -1,141 +1,148 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
-using System.Data.Entity;
using System.Linq;
-using Xunit;
+using System.Threading.Tasks;
+using AutoMapper.UnitTests;
+using Microsoft.EntityFrameworkCore;
using Shouldly;
+using Xunit;
-namespace AutoMapper.IntegrationTests.Net4
-{
- using UnitTests;
- using QueryableExtensions;
+namespace AutoMapper.IntegrationTests.BuiltInTypes;
- public class ProjectUsingWithNullables : AutoMapperSpecBase
+public class ProjectUsingWithNullables : AutoMapperSpecBase, IAsyncLifetime
+{
+ public class MyProfile : Profile
{
- public class MyProfile : Profile
+ public MyProfile()
{
- public MyProfile()
- {
- CreateProjection();
- CreateProjection().ConvertUsing(x => (MyEnum)x);
- CreateProjection().ConvertUsing(x => x.HasValue ? (MyEnum)x.Value : MyEnum.Value1);
- }
+ CreateProjection();
+ CreateProjection().ConvertUsing(x => (MyEnum)x);
+ CreateProjection().ConvertUsing(x => x.HasValue ? (MyEnum)x.Value : MyEnum.Value1);
}
+ }
- public enum MyEnum
- {
- Value1 = 0,
- Value2 = 1
- }
+ public enum MyEnum
+ {
+ Value1 = 0,
+ Value2 = 1
+ }
- public class MyTable
- {
- public int Id { get; set; }
- public int EnumValue { get; set; }
- public int? EnumValueNullable { get; set; }
- }
+ public class MyTable
+ {
+ public int Id { get; set; }
+ public int EnumValue { get; set; }
+ public int? EnumValueNullable { get; set; }
+ }
- public class MyTableModel
- {
- public int Id { get; set; }
- public MyEnum EnumValue { get; set; }
- public MyEnum EnumValueNullable { get; set; }
- }
+ public class MyTableModel
+ {
+ public int Id { get; set; }
+ public MyEnum EnumValue { get; set; }
+ public MyEnum EnumValueNullable { get; set; }
+ }
- public class DatabaseInitializer : CreateDatabaseIfNotExists
+ public class DatabaseInitializer : CreateDatabaseIfNotExists
+ {
+ protected override void Seed(TestContext context)
{
- protected override void Seed(TestContext context)
- {
- context.MyTable.AddRange(new[]{
- new MyTable { Id = 1, EnumValue = (int)MyEnum.Value2 },
- new MyTable { Id = 2, EnumValueNullable = (int?)MyEnum.Value1 },
- });
- base.Seed(context);
- }
+ context.MyTable.AddRange(new[]{
+ new MyTable { EnumValue = (int)MyEnum.Value2 },
+ new MyTable { EnumValueNullable = (int?)MyEnum.Value1 },
+ });
+ base.Seed(context);
}
+ }
- public class TestContext : DbContext
- {
- public TestContext()
- {
- Database.SetInitializer(new DatabaseInitializer());
- }
- public DbSet MyTable { get; set; }
- }
- protected override MapperConfiguration CreateConfiguration() => new(cfg => cfg.AddProfile());
+ public class TestContext : LocalDbContext
+ {
+ public DbSet MyTable { get; set; }
+ }
+ protected override MapperConfiguration CreateConfiguration() => new(cfg => cfg.AddProfile());
- [Fact]
- public void Should_project_ok()
+ [Fact]
+ public void Should_project_ok()
+ {
+ using(var context = new TestContext())
{
- using(var context = new TestContext())
- {
- var results = ProjectTo(context.MyTable).ToList();
- results[0].Id.ShouldBe(1);
- results[0].EnumValue.ShouldBe(MyEnum.Value2);
- results[0].EnumValueNullable.ShouldBe(MyEnum.Value1);
- results[1].Id.ShouldBe(2);
- results[1].EnumValue.ShouldBe(MyEnum.Value1);
- results[1].EnumValueNullable.ShouldBe(MyEnum.Value1);
- }
+ var results = ProjectTo(context.MyTable).ToList();
+ results[0].Id.ShouldBe(1);
+ results[0].EnumValue.ShouldBe(MyEnum.Value2);
+ results[0].EnumValueNullable.ShouldBe(MyEnum.Value1);
+ results[1].Id.ShouldBe(2);
+ results[1].EnumValue.ShouldBe(MyEnum.Value1);
+ results[1].EnumValueNullable.ShouldBe(MyEnum.Value1);
}
}
- public class ProjectUsingBug : AutoMapperSpecBase
+ public async Task InitializeAsync()
{
- public class Parent
- {
- [Key]
- public int ID { get; set; }
- public string ParentTitle { get; set; }
+ var initializer = new DatabaseInitializer();
- public ICollection Children { get; set; }
- }
+ await initializer.Migrate();
+ }
- public class Children
- {
- public int ID { get; set; }
- public string ChildTitle { get; set; }
- }
+ public Task DisposeAsync() => Task.CompletedTask;
+}
- public class ParentVM
- {
- [Key]
- public int ID { get; set; }
- public string ParentTitle { get; set; }
- public List Children { get; set; }
- }
+public class ProjectUsingBug : AutoMapperSpecBase, IAsyncLifetime
+{
+ public class Parent
+ {
+ [Key]
+ public int ID { get; set; }
+ public string ParentTitle { get; set; }
+
+ public ICollection Children { get; set; }
+ }
+
+ public class Children
+ {
+ public int ID { get; set; }
+ public string ChildTitle { get; set; }
+ }
+
+ public class ParentVM
+ {
+ [Key]
+ public int ID { get; set; }
+ public string ParentTitle { get; set; }
+ public List Children { get; set; }
+ }
- public partial class ApplicationDBContext : DbContext
+ public partial class ApplicationDBContext : LocalDbContext
+ {
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
{
- public ApplicationDBContext()
- {
- Database.SetInitializer(new CreateDatabaseIfNotExists());
- }
-
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- modelBuilder.Entity()
- .HasMany(x => x.Children);
- }
-
- public DbSet Parents { get; set; }
- public DbSet Children { get; set; }
+ modelBuilder.Entity()
+ .HasMany(x => x.Children);
}
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection();
- cfg.CreateProjection()
- .ConvertUsing(c => c.ID);
- });
+ public DbSet Parents { get; set; }
+ public DbSet Children { get; set; }
+ }
+
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection();
+ cfg.CreateProjection()
+ .ConvertUsing(c => c.ID);
+ });
- [Fact]
- public void can_map_with_projection()
+ [Fact]
+ public void can_map_with_projection()
+ {
+ using (var db = new ApplicationDBContext())
{
- using (var db = new ApplicationDBContext())
- {
- var result = ProjectTo(db.Parents);
- }
+ var result = ProjectTo(db.Parents);
}
}
+
+ public async Task InitializeAsync()
+ {
+ var initializer = new CreateDatabaseIfNotExists();
+
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
}
\ No newline at end of file
diff --git a/src/IntegrationTests/ChildClassTests.cs b/src/IntegrationTests/ChildClassTests.cs
index 5c9a9f81bb..3aa6119111 100644
--- a/src/IntegrationTests/ChildClassTests.cs
+++ b/src/IntegrationTests/ChildClassTests.cs
@@ -1,17 +1,16 @@
-using System.ComponentModel.DataAnnotations;
-using System.Data.Entity;
+using System;
+using System.ComponentModel.DataAnnotations;
using System.Linq;
-using Xunit;
+using System.Threading.Tasks;
+using AutoMapper.UnitTests;
+using Microsoft.EntityFrameworkCore;
using Shouldly;
+using Xunit;
-namespace AutoMapper.IntegrationTests.Net4
+namespace AutoMapper.IntegrationTests
{
namespace ChildClassTests
{
- using AutoMapper.UnitTests;
- using QueryableExtensions;
- using System;
-
public class Base
{
public int BaseID { get; set; }
@@ -44,31 +43,24 @@ public class SubDTO
public string Sub1 { get; set; }
}
- public class TestContext : DbContext
+ public class TestContext : LocalDbContext
{
- public TestContext()
- : base()
- {
- Database.SetInitializer(new DatabaseInitializer());
- }
-
public DbSet Bases { get; set; }
public DbSet Subs { get; set; }
-
}
public class DatabaseInitializer : DropCreateDatabaseAlways
{
protected override void Seed(TestContext testContext)
{
- testContext.Bases.Add(new Base() { BaseID = 1, Base1 = "base1", Sub = new Sub() { BaseId = 1, Sub1 = "sub1" } });
+ testContext.Bases.Add(new Base() { Base1 = "base1", Sub = new Sub() { Sub1 = "sub1" } });
base.Seed(testContext);
}
}
- public class UnitTest : AutoMapperSpecBase
+ public class UnitTest : AutoMapperSpecBase, IAsyncLifetime
{
protected override MapperConfiguration CreateConfiguration() => new(cfg =>
{
@@ -81,7 +73,7 @@ public void AutoMapperEFRelationsTest()
{
using (var context = new TestContext())
{
- var baseEntitiy = context.Bases.FirstOrDefault();
+ var baseEntitiy = context.Bases.Include(b => b.Sub).FirstOrDefault();
baseEntitiy.ShouldNotBeNull();
baseEntitiy.BaseID.ShouldBe(1);
baseEntitiy.Sub.Sub1.ShouldBe("sub1");
@@ -111,6 +103,15 @@ public void AutoMapperEFRelationsTest()
}
[Fact]
public void MapShouldThrow() => new Action(() => Mapper.Map(new Sub())).ShouldThrow().Message.ShouldBe("CreateProjection works with ProjectTo, not with Map.");
+
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
+
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
}
}
diff --git a/src/IntegrationTests/CreateDatabaseIfNotExists.cs b/src/IntegrationTests/CreateDatabaseIfNotExists.cs
new file mode 100644
index 0000000000..d6ef719cd2
--- /dev/null
+++ b/src/IntegrationTests/CreateDatabaseIfNotExists.cs
@@ -0,0 +1,30 @@
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+
+namespace AutoMapper.IntegrationTests;
+
+public class CreateDatabaseIfNotExists : DropCreateDatabaseAlways
+ where TContext : DbContext, new()
+{
+
+}
+
+public class DropCreateDatabaseAlways where TContext : DbContext, new()
+{
+ protected virtual void Seed(TContext context)
+ {
+
+ }
+
+ public async Task Migrate()
+ {
+ await using var context = new TContext();
+
+ await context.Database.EnsureDeletedAsync();
+ await context.Database.EnsureCreatedAsync();
+
+ Seed(context);
+
+ await context.SaveChangesAsync();
+ }
+}
\ No newline at end of file
diff --git a/src/IntegrationTests/CustomMapFrom/CustomMapFromTest.cs b/src/IntegrationTests/CustomMapFrom/CustomMapFromTest.cs
index 2dc38923f4..dd70b2ca6e 100644
--- a/src/IntegrationTests/CustomMapFrom/CustomMapFromTest.cs
+++ b/src/IntegrationTests/CustomMapFrom/CustomMapFromTest.cs
@@ -1,18 +1,15 @@
-using System;
-using System.Collections.Generic;
-using System.ComponentModel.DataAnnotations;
-using System.Data.Entity;
+using System.ComponentModel.DataAnnotations;
using System.Linq;
-using Xunit;
+using System.Threading.Tasks;
+using AutoMapper.UnitTests;
+using Microsoft.EntityFrameworkCore;
using Shouldly;
+using Xunit;
-namespace AutoMapper.IntegrationTests.Net4
+namespace AutoMapper.IntegrationTests.CustomMapFrom
{
namespace CustomMapFromTest
{
- using AutoMapper.UnitTests;
- using QueryableExtensions;
-
public class Customer
{
[Key]
@@ -40,14 +37,8 @@ public class CustomerViewModel
public string FullAddress { get; set; }
}
- public class Context : DbContext
+ public class Context : LocalDbContext
{
- public Context()
- : base()
- {
- Database.SetInitializer(new DatabaseInitializer());
- }
-
public DbSet Customers { get; set; }
public DbSet Addresses { get; set; }
@@ -59,12 +50,10 @@ protected override void Seed(Context context)
{
context.Customers.Add(new Customer
{
- Id = 1,
FirstName = "Bob",
LastName = "Smith",
Address = new Address
{
- Id = 1,
Street = "123 Anywhere",
City = "Austin",
State = "TX"
@@ -75,7 +64,7 @@ protected override void Seed(Context context)
}
}
- public class AutoMapperQueryableExtensionsThrowsNullReferenceExceptionSpec : AutoMapperSpecBase
+ public class AutoMapperQueryableExtensionsThrowsNullReferenceExceptionSpec : AutoMapperSpecBase, IAsyncLifetime
{
protected override MapperConfiguration CreateConfiguration() => new(cfg =>
{
@@ -110,6 +99,15 @@ public void can_map_with_projection()
});
}
}
+
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
+
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
}
}
}
\ No newline at end of file
diff --git a/src/IntegrationTests/CustomMapFrom/MapObjectPropertyFromSubQuery.cs b/src/IntegrationTests/CustomMapFrom/MapObjectPropertyFromSubQuery.cs
index 9098d22d9b..2b4d1010bd 100644
--- a/src/IntegrationTests/CustomMapFrom/MapObjectPropertyFromSubQuery.cs
+++ b/src/IntegrationTests/CustomMapFrom/MapObjectPropertyFromSubQuery.cs
@@ -1,1028 +1,1079 @@
-using Shouldly;
-using System.Linq;
-using System.Collections.Generic;
-using AutoMapper.UnitTests;
-using System.Data.Entity;
-using Xunit;
+using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
+using System.Linq;
using System.Linq.Expressions;
-namespace AutoMapper.IntegrationTests
+using System.Threading.Tasks;
+using AutoMapper.UnitTests;
+using Microsoft.EntityFrameworkCore;
+using Shouldly;
+using Xunit;
+
+namespace AutoMapper.IntegrationTests.CustomMapFrom;
+
+public class MemberWithSubQueryProjections : AutoMapperSpecBase, IAsyncLifetime
{
- public class MemberWithSubQueryProjections : AutoMapperSpecBase
+ public class Customer
{
- public class Customer
- {
- [Key]
- public int Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public ICollection
- Items { get; set; }
- }
- public class Item
- {
- public int Id { get; set; }
- public int Code { get; set; }
- }
- public class ItemModel
- {
- public int Id { get; set; }
- public int Code { get; set; }
- }
- public class CustomerViewModel
- {
- public CustomerNameModel Name { get; set; }
- public ItemModel FirstItem { get; set; }
- }
- public class CustomerNameModel
- {
- public string FirstName { get; set; }
- public string LastName { get; set; }
- }
- public class Context : DbContext
- {
- public Context() => Database.SetInitializer(new DatabaseInitializer());
- public DbSet Customers { get; set; }
- }
- public class DatabaseInitializer : DropCreateDatabaseAlways
- {
- protected override void Seed(Context context)
- {
- context.Customers.Add(new Customer
- {
- Id = 1, FirstName = "Bob", LastName = "Smith", Items = new[] { new Item { Code = 1 }, new Item { Code = 3 }, new Item { Code = 5 } }
- });
- base.Seed(context);
- }
- }
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection()
- .ForMember(dst => dst.Name, opt => opt.MapFrom(src => src.LastName != null ? src : null))
- .ForMember(dst => dst.FirstItem, opt => opt.MapFrom(src => src.Items.FirstOrDefault()));
- cfg.CreateProjection();
- cfg.CreateProjection
- ();
- });
- [Fact]
- public void Should_work()
- {
- using (var context = new Context())
- {
- var resultQuery = ProjectTo(context.Customers);
- var result = resultQuery.Single();
- result.Name.FirstName.ShouldBe("Bob");
- result.Name.LastName.ShouldBe("Smith");
- result.FirstItem.Id.ShouldBe(1);
- result.FirstItem.Code.ShouldBe(1);
- }
- }
+ [Key]
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public ICollection
- Items { get; set; }
}
- public class MemberWithSubQueryProjectionsNoMap : AutoMapperSpecBase
+ public class Item
{
- public class Customer
- {
- [Key]
- public int Id { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public ICollection
- Items { get; set; }
- }
- public class Item
- {
- public int Id { get; set; }
- public int Code { get; set; }
- }
- public class ItemModel
- {
- public int Id { get; set; }
- public int Code { get; set; }
- }
- public class CustomerViewModel
- {
- public string Name { get; set; }
- public ItemModel FirstItem { get; set; }
- }
- public class Context : DbContext
- {
- public Context() => Database.SetInitializer(new DatabaseInitializer());
- public DbSet Customers { get; set; }
- }
- public class DatabaseInitializer : DropCreateDatabaseAlways
- {
- protected override void Seed(Context context)
- {
- context.Customers.Add(new Customer
- {
- Id = 1,
- FirstName = "Bob",
- LastName = "Smith",
- Items = new[] { new Item { Code = 1 }, new Item { Code = 3 }, new Item { Code = 5 } }
- });
- base.Seed(context);
- }
- }
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection()
- .ForMember(dst => dst.Name, opt => opt.MapFrom(src => src.LastName != null ? src.LastName : null))
- .ForMember(dst => dst.FirstItem, opt => opt.MapFrom(src => src.Items.FirstOrDefault()));
- cfg.CreateProjection
- ();
- });
- [Fact]
- public void Should_work()
+ public int Id { get; set; }
+ public int Code { get; set; }
+ }
+ public class ItemModel
+ {
+ public int Id { get; set; }
+ public int Code { get; set; }
+ }
+ public class CustomerViewModel
+ {
+ public CustomerNameModel Name { get; set; }
+ public ItemModel FirstItem { get; set; }
+ }
+ public class CustomerNameModel
+ {
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ }
+ public class Context : LocalDbContext
+ {
+ public DbSet Customers { get; set; }
+ }
+ public class DatabaseInitializer : DropCreateDatabaseAlways
+ {
+ protected override void Seed(Context context)
{
- using (var context = new Context())
+ context.Customers.Add(new Customer
{
- var resultQuery = ProjectTo(context.Customers);
- var result = resultQuery.Single();
- result.Name.ShouldBe("Smith");
- result.FirstItem.Id.ShouldBe(1);
- result.FirstItem.Code.ShouldBe(1);
- }
+ FirstName = "Bob",
+ LastName = "Smith",
+ Items = new[] { new Item { Code = 1 }, new Item { Code = 3 }, new Item { Code = 5 } }
+ });
+ base.Seed(context);
}
}
- public class MapObjectPropertyFromSubQueryTypeNameMax : AutoMapperSpecBase
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
{
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection()
- .ForMember(d => d.Price, o => o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault()));
- cfg.CreateProjection()
- .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
- });
-
- [Fact]
- public void Should_cache_the_subquery()
+ cfg.CreateProjection()
+ .ForMember(dst => dst.Name, opt => opt.MapFrom(src => src.LastName != null ? src : null))
+ .ForMember(dst => dst.FirstItem, opt => opt.MapFrom(src => src.Items.FirstOrDefault()));
+ cfg.CreateProjection();
+ cfg.CreateProjection
- ();
+ });
+ [Fact]
+ public void Should_work()
+ {
+ using (var context = new Context())
{
- using(var context = new ClientContext())
- {
- var projection = ProjectTo(context.Products);
- var counter = new FirstOrDefaultCounter();
- counter.Visit(projection.Expression);
- counter.Count.ShouldBe(1);
- var productModel = projection.First();
- productModel.Price.RegionId.ShouldBe((short)1);
- productModel.Price.IsDefault.ShouldBeTrue();
- productModel.Price.Id.ShouldBe(1);
- productModel.Id.ShouldBe(1);
- }
+ var resultQuery = ProjectTo(context.Customers);
+ var result = resultQuery.Single();
+ result.Name.FirstName.ShouldBe("Bob");
+ result.Name.LastName.ShouldBe("Smith");
+ result.FirstItem.Id.ShouldBe(1);
+ result.FirstItem.Code.ShouldBe(1);
}
+ }
- class FirstOrDefaultCounter : ExpressionVisitor
- {
- public int Count;
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
- protected override Expression VisitMethodCall(MethodCallExpression node)
- {
- if(node.Method.Name == "FirstOrDefault")
- {
- Count++;
- }
- return base.VisitMethodCall(node);
- }
- }
+ await initializer.Migrate();
+ }
- public partial class Article
+ public Task DisposeAsync() => Task.CompletedTask;
+}
+public class MemberWithSubQueryProjectionsNoMap : AutoMapperSpecBase, IAsyncLifetime
+{
+ public class Customer
+ {
+ [Key]
+ public int Id { get; set; }
+ public string FirstName { get; set; }
+ public string LastName { get; set; }
+ public ICollection
- Items { get; set; }
+ }
+ public class Item
+ {
+ public int Id { get; set; }
+ public int Code { get; set; }
+ }
+ public class ItemModel
+ {
+ public int Id { get; set; }
+ public int Code { get; set; }
+ }
+ public class CustomerViewModel
+ {
+ public string Name { get; set; }
+ public ItemModel FirstItem { get; set; }
+ }
+ public class Context : LocalDbContext
+ {
+ public DbSet Customers { get; set; }
+ }
+ public class DatabaseInitializer : DropCreateDatabaseAlways
+ {
+ protected override void Seed(Context context)
{
- public int Id { get; set; }
- public int ProductId { get; set; }
- public bool IsDefault { get; set; }
- public short NationId { get; set; }
- public virtual Product Product { get; set; }
+ context.Customers.Add(new Customer
+ {
+ FirstName = "Bob",
+ LastName = "Smith",
+ Items = new[] { new Item { Code = 1 }, new Item { Code = 3 }, new Item { Code = 5 } }
+ });
+ base.Seed(context);
}
-
- public partial class Product
+ }
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection()
+ .ForMember(dst => dst.Name, opt => opt.MapFrom(src => src.LastName != null ? src.LastName : null))
+ .ForMember(dst => dst.FirstItem, opt => opt.MapFrom(src => src.Items.FirstOrDefault()));
+ cfg.CreateProjection
- ();
+ });
+ [Fact]
+ public void Should_work()
+ {
+ using (var context = new Context())
{
- public int Id { get; set; }
- public string Name { get; set; }
- public bool ECommercePublished { get; set; }
- public virtual ICollection Articles { get; set; }
- public int Value { get; }
- [NotMapped]
- public int NotMappedValue { get; set; }
- public virtual List OtherArticles { get; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName1 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName2 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName3 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName4 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName5 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName6 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName7 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName8 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName9 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName10 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName11 { get; set; }
+ var resultQuery = ProjectTo(context.Customers);
+ var result = resultQuery.Single();
+ result.Name.ShouldBe("Smith");
+ result.FirstItem.Id.ShouldBe(1);
+ result.FirstItem.Code.ShouldBe(1);
}
+ }
- public class PriceModel
- {
- public int Id { get; set; }
- public short RegionId { get; set; }
- public bool IsDefault { get; set; }
- }
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
- public class ProductModel
- {
- public int Id { get; set; }
- public PriceModel Price { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName1 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName2 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName3 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName4 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName5 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName6 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName7 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName8 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName9 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName10 { get; set; }
- public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName11 { get; set; }
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
+}
+public class MapObjectPropertyFromSubQueryTypeNameMax : AutoMapperSpecBase, IAsyncLifetime
+{
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection()
+ .ForMember(d => d.Price, o => o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault()));
+ cfg.CreateProjection()
+ .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
+ });
+
+ [Fact]
+ public void Should_cache_the_subquery()
+ {
+ using (var context = new ClientContext())
+ {
+ var projection = ProjectTo(context.Products);
+ var counter = new FirstOrDefaultCounter();
+ counter.Visit(projection.Expression);
+ counter.Count.ShouldBe(1);
+ var productModel = projection.First();
+ productModel.Price.RegionId.ShouldBe((short)1);
+ productModel.Price.IsDefault.ShouldBeTrue();
+ productModel.Price.Id.ShouldBe(1);
+ productModel.Id.ShouldBe(1);
}
+ }
+
+ class FirstOrDefaultCounter : ExpressionVisitor
+ {
+ public int Count;
- class Initializer : DropCreateDatabaseAlways
+ protected override Expression VisitMethodCall(MethodCallExpression node)
{
- protected override void Seed(ClientContext context)
+ if (node.Method.Name == "FirstOrDefault")
{
- context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
+ Count++;
}
+ return base.VisitMethodCall(node);
}
+ }
- class ClientContext : DbContext
- {
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- Database.SetInitializer(new Initializer());
- }
+ public partial class Article
+ {
+ public int Id { get; set; }
+ public int ProductId { get; set; }
+ public bool IsDefault { get; set; }
+ public short NationId { get; set; }
+ public virtual Product Product { get; set; }
+ }
- public DbSet Products { get; set; }
- }
+ public partial class Product
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public bool ECommercePublished { get; set; }
+ public virtual ICollection Articles { get; set; }
+ public int Value { get; }
+ [NotMapped]
+ public int NotMappedValue { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName1 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName2 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName3 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName4 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName5 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName6 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName7 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName8 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName9 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName10 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName11 { get; set; }
}
- public class MapObjectPropertyFromSubQueryExplicitExpansion : AutoMapperSpecBase
+ public class PriceModel
{
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection()
- .ForMember(d => d.Price, o =>
- {
- o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault());
- o.ExplicitExpansion();
- });
- cfg.CreateProjection()
- .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
- });
-
- [Fact]
- public void Should_map_ok()
+ public int Id { get; set; }
+ public short RegionId { get; set; }
+ public bool IsDefault { get; set; }
+ }
+
+ public class ProductModel
+ {
+ public int Id { get; set; }
+ public PriceModel Price { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName1 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName2 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName3 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName4 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName5 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName6 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName7 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName8 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName9 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName10 { get; set; }
+ public int VeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnNameVeryLongColumnName11 { get; set; }
+ }
+
+ class DatabaseInitializer : DropCreateDatabaseAlways
+ {
+ protected override void Seed(ClientContext context)
{
- using(var context = new ClientContext())
- {
- var projection = ProjectTo(context.Products);
- var counter = new FirstOrDefaultCounter();
- counter.Visit(projection.Expression);
- counter.Count.ShouldBe(0);
- var productModel = projection.First();
- productModel.Price.ShouldBeNull();
- productModel.Id.ShouldBe(1);
- }
+ context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
}
+ }
- class FirstOrDefaultCounter : ExpressionVisitor
- {
- public int Count;
+ class ClientContext : LocalDbContext
+ {
+ public DbSet Products { get; set; }
+ }
- protected override Expression VisitMethodCall(MethodCallExpression node)
- {
- if(node.Method.Name == "FirstOrDefault")
- {
- Count++;
- }
- return base.VisitMethodCall(node);
- }
- }
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
- public partial class Article
- {
- public int Id { get; set; }
- public int ProductId { get; set; }
- public bool IsDefault { get; set; }
- public short NationId { get; set; }
- public virtual Product Product { get; set; }
- }
+ await initializer.Migrate();
+ }
- public partial class Product
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public bool ECommercePublished { get; set; }
- public virtual ICollection Articles { get; set; }
- public int Value { get; }
- public virtual List OtherArticles { get; }
- }
+ public Task DisposeAsync() => Task.CompletedTask;
+}
- public class PriceModel
+public class MapObjectPropertyFromSubQueryExplicitExpansion : AutoMapperSpecBase, IAsyncLifetime
+{
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection()
+ .ForMember(d => d.Price, o =>
+ {
+ o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault());
+ o.ExplicitExpansion();
+ });
+ cfg.CreateProjection()
+ .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
+ });
+
+ [Fact]
+ public void Should_map_ok()
+ {
+ using (var context = new ClientContext())
{
- public int Id { get; set; }
- public short RegionId { get; set; }
- public bool IsDefault { get; set; }
+ var projection = ProjectTo(context.Products);
+ var counter = new FirstOrDefaultCounter();
+ counter.Visit(projection.Expression);
+ counter.Count.ShouldBe(0);
+ var productModel = projection.First();
+ productModel.Price.ShouldBeNull();
+ productModel.Id.ShouldBe(1);
}
+ }
- public class ProductModel
- {
- public int Id { get; set; }
- public PriceModel Price { get; set; }
- }
+ class FirstOrDefaultCounter : ExpressionVisitor
+ {
+ public int Count;
- class Initializer : DropCreateDatabaseAlways
+ protected override Expression VisitMethodCall(MethodCallExpression node)
{
- protected override void Seed(ClientContext context)
+ if (node.Method.Name == "FirstOrDefault")
{
- context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
+ Count++;
}
+ return base.VisitMethodCall(node);
}
+ }
- class ClientContext : DbContext
- {
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- Database.SetInitializer(new Initializer());
- }
+ public partial class Article
+ {
+ public int Id { get; set; }
+ public int ProductId { get; set; }
+ public bool IsDefault { get; set; }
+ public short NationId { get; set; }
+ public virtual Product Product { get; set; }
+ }
- public DbSet Products { get; set; }
- }
+ public partial class Product
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public bool ECommercePublished { get; set; }
+ public virtual ICollection Articles { get; set; }
+ public int Value { get; }
}
- public class MapObjectPropertyFromSubQuery : AutoMapperSpecBase
+ public class PriceModel
{
- protected override MapperConfiguration CreateConfiguration() => new(cfg=>
- {
- cfg.CreateProjection()
- .ForMember(d => d.Price, o => o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault()));
- cfg.CreateProjection()
- .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
- });
-
- [Fact]
- public void Should_cache_the_subquery()
+ public int Id { get; set; }
+ public short RegionId { get; set; }
+ public bool IsDefault { get; set; }
+ }
+
+ public class ProductModel
+ {
+ public int Id { get; set; }
+ public PriceModel Price { get; set; }
+ }
+
+ class DatabaseInitializer : DropCreateDatabaseAlways
+ {
+ protected override void Seed(ClientContext context)
{
- using(var context = new ClientContext())
- {
- var projection = ProjectTo(context.Products);
- var counter = new FirstOrDefaultCounter();
- counter.Visit(projection.Expression);
- counter.Count.ShouldBe(1);
- var productModel = projection.First();
- productModel.Price.RegionId.ShouldBe((short)1);
- productModel.Price.IsDefault.ShouldBeTrue();
- productModel.Price.Id.ShouldBe(1);
- productModel.Id.ShouldBe(1);
- }
+ context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
}
+ }
- class FirstOrDefaultCounter : ExpressionVisitor
- {
- public int Count;
+ class ClientContext : LocalDbContext
+ {
+ public DbSet Products { get; set; }
+ public DbSet Articles { get; set; }
+ }
- protected override Expression VisitMethodCall(MethodCallExpression node)
- {
- if(node.Method.Name == "FirstOrDefault")
- {
- Count++;
- }
- return base.VisitMethodCall(node);
- }
- }
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
- public partial class Article
- {
- public int Id { get; set; }
- public int ProductId { get; set; }
- public bool IsDefault { get; set; }
- public short NationId { get; set; }
- public virtual Product Product { get; set; }
- }
+ await initializer.Migrate();
+ }
- public partial class Product
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public bool ECommercePublished { get; set; }
- public virtual ICollection Articles { get; set; }
- public int Value { get; }
- [NotMapped]
- public int NotMappedValue { get; set; }
- public virtual List OtherArticles { get; }
- }
+ public Task DisposeAsync() => Task.CompletedTask;
+}
- public class PriceModel
- {
- public int Id { get; set; }
- public short RegionId { get; set; }
- public bool IsDefault { get; set; }
+public class MapObjectPropertyFromSubQuery : AutoMapperSpecBase, IAsyncLifetime
+{
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection()
+ .ForMember(d => d.Price, o => o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault()));
+ cfg.CreateProjection()
+ .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
+ });
+
+ [Fact]
+ public void Should_cache_the_subquery()
+ {
+ using (var context = new ClientContext())
+ {
+ var projection = ProjectTo(context.Products);
+ var counter = new FirstOrDefaultCounter();
+ counter.Visit(projection.Expression);
+ counter.Count.ShouldBe(1);
+ var productModel = projection.First();
+ productModel.Price.RegionId.ShouldBe((short)1);
+ productModel.Price.IsDefault.ShouldBeTrue();
+ productModel.Price.Id.ShouldBe(1);
+ productModel.Id.ShouldBe(1);
}
+ }
- public class ProductModel
- {
- public int Id { get; set; }
- public PriceModel Price { get; set; }
- }
+ class FirstOrDefaultCounter : ExpressionVisitor
+ {
+ public int Count;
- class Initializer : DropCreateDatabaseAlways
+ protected override Expression VisitMethodCall(MethodCallExpression node)
{
- protected override void Seed(ClientContext context)
+ if (node.Method.Name == "FirstOrDefault")
{
- context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
+ Count++;
}
+ return base.VisitMethodCall(node);
}
+ }
- class ClientContext : DbContext
- {
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- Database.SetInitializer(new Initializer());
- }
+ public partial class Article
+ {
+ public int Id { get; set; }
+ public int ProductId { get; set; }
+ public bool IsDefault { get; set; }
+ public short NationId { get; set; }
+ public virtual Product Product { get; set; }
+ }
- public DbSet Products { get; set; }
- }
+ public partial class Product
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public bool ECommercePublished { get; set; }
+ public virtual ICollection Articles { get; set; }
+ public int Value { get; }
+ [NotMapped]
+ public int NotMappedValue { get; set; }
}
- public class MapObjectPropertyFromSubQueryWithInnerObject : AutoMapperSpecBase
+ public class PriceModel
{
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection();
- cfg.CreateProjection()
- .ForMember(d => d.Price, o => o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault()));
- cfg.CreateProjection()
- .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
- });
-
- [Fact]
- public void Should_cache_the_subquery()
- {
- using(var context = new ClientContext())
- {
- var projection = ProjectTo(context.ProductArticles);
- var counter = new FirstOrDefaultCounter();
- counter.Visit(projection.Expression);
- counter.Count.ShouldBe(2);
- var productArticleModel = projection.First();
- var productModel = productArticleModel.Product;
- productModel.Price.RegionId.ShouldBe((short)1);
- productModel.Price.IsDefault.ShouldBeTrue();
- productModel.Price.Id.ShouldBe(1);
- productModel.Id.ShouldBe(1);
- var otherProductModel = productArticleModel.OtherProduct;
- otherProductModel.Price.RegionId.ShouldBe((short)1);
- otherProductModel.Price.IsDefault.ShouldBeTrue();
- otherProductModel.Price.Id.ShouldBe(2);
- otherProductModel.Id.ShouldBe(2);
- }
- }
+ public int Id { get; set; }
+ public short RegionId { get; set; }
+ public bool IsDefault { get; set; }
+ }
- public class ProductArticle
- {
- public int Id { get; set; }
- public Product Product { get; set; }
- public Product OtherProduct { get; set; }
- }
+ public class ProductModel
+ {
+ public int Id { get; set; }
+ public PriceModel Price { get; set; }
+ }
- public class ProductArticleModel
+ class DatabaseInitializer : DropCreateDatabaseAlways
+ {
+ protected override void Seed(ClientContext context)
{
- public int Id { get; set; }
- public ProductModel Product { get; set; }
- public ProductModel OtherProduct { get; set; }
+ context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
}
+ }
- public partial class Article
- {
- public int Id { get; set; }
- public int ProductId { get; set; }
- public bool IsDefault { get; set; }
- public short NationId { get; set; }
- public virtual Product Product { get; set; }
- }
+ class ClientContext : LocalDbContext
+ {
+ public DbSet Products { get; set; }
+ }
- public partial class Product
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public bool ECommercePublished { get; set; }
- public virtual ICollection Articles { get; set; }
- }
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
- public class PriceModel
- {
- public int Id { get; set; }
- public short RegionId { get; set; }
- public bool IsDefault { get; set; }
- }
+ await initializer.Migrate();
+ }
- public class ProductModel
- {
- public int Id { get; set; }
- public PriceModel Price { get; set; }
- }
+ public Task DisposeAsync() => Task.CompletedTask;
+}
- class Initializer : DropCreateDatabaseAlways
- {
- protected override void Seed(ClientContext context)
- {
- var product1 = context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
- var product2 = context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 2 } } });
- context.ProductArticles.Add(new ProductArticle { Product = product1, OtherProduct = product2 });
- }
+public class MapObjectPropertyFromSubQueryWithInnerObject : AutoMapperSpecBase, IAsyncLifetime
+{
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection();
+ cfg.CreateProjection()
+ .ForMember(d => d.Price, o => o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault()));
+ cfg.CreateProjection()
+ .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
+ });
+
+ [Fact]
+ public void Should_cache_the_subquery()
+ {
+ using (var context = new ClientContext())
+ {
+ var projection = ProjectTo(context.ProductArticles);
+ var counter = new FirstOrDefaultCounter();
+ counter.Visit(projection.Expression);
+ counter.Count.ShouldBe(2);
+ var productArticleModel = projection.First();
+ var productModel = productArticleModel.Product;
+ productModel.Price.RegionId.ShouldBe((short)1);
+ productModel.Price.IsDefault.ShouldBeTrue();
+ productModel.Price.Id.ShouldBe(1);
+ productModel.Id.ShouldBe(1);
+ var otherProductModel = productArticleModel.OtherProduct;
+ otherProductModel.Price.RegionId.ShouldBe((short)1);
+ otherProductModel.Price.IsDefault.ShouldBeTrue();
+ otherProductModel.Price.Id.ShouldBe(2);
+ otherProductModel.Id.ShouldBe(2);
}
+ }
- class ClientContext : DbContext
- {
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- Database.SetInitializer(new Initializer());
- }
+ public class ProductArticle
+ {
+ public int Id { get; set; }
+ public Product Product { get; set; }
+ public Product OtherProduct { get; set; }
+ }
- public DbSet Products { get; set; }
- public DbSet ProductArticles { get; set; }
- }
+ public class ProductArticleModel
+ {
+ public int Id { get; set; }
+ public ProductModel Product { get; set; }
+ public ProductModel OtherProduct { get; set; }
}
- public class MapObjectPropertyFromSubQueryWithCollection : AutoMapperSpecBase
+ public partial class Article
{
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection();
- cfg.CreateProjection()
- .ForMember(d => d.Price, o => o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault()));
- cfg.CreateProjection()
- .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
- });
-
- [Fact]
- public void Should_cache_the_subquery()
- {
- using(var context = new ClientContext())
- {
- var projection = ProjectTo(context.ProductArticles);
- var counter = new FirstOrDefaultCounter();
- counter.Visit(projection.Expression);
- counter.Count.ShouldBe(1);
- var productModel = projection.First().Products.First();
- productModel.Price.RegionId.ShouldBe((short)1);
- productModel.Price.IsDefault.ShouldBeTrue();
- productModel.Price.Id.ShouldBe(1);
- productModel.Id.ShouldBe(1);
- }
- }
+ public int Id { get; set; }
+ public int ProductId { get; set; }
+ public bool IsDefault { get; set; }
+ public short NationId { get; set; }
+ public virtual Product Product { get; set; }
+ }
- class FirstOrDefaultCounter : ExpressionVisitor
- {
- public int Count;
+ public partial class Product
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public bool ECommercePublished { get; set; }
+ public virtual ICollection Articles { get; set; }
+ }
- protected override Expression VisitMethodCall(MethodCallExpression node)
- {
- if(node.Method.Name == "FirstOrDefault")
- {
- Count++;
- }
- return base.VisitMethodCall(node);
- }
- }
+ public class PriceModel
+ {
+ public int Id { get; set; }
+ public short RegionId { get; set; }
+ public bool IsDefault { get; set; }
+ }
- public class ProductArticle
- {
- public int Id { get; set; }
- public ICollection Products { get; set; }
- }
+ public class ProductModel
+ {
+ public int Id { get; set; }
+ public PriceModel Price { get; set; }
+ }
- public class ProductArticleModel
+ class DatabaseInitializer : DropCreateDatabaseAlways
+ {
+ protected override void Seed(ClientContext context)
{
- public int Id { get; set; }
- public ICollection Products { get; set; }
+ var product1 = context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
+ var product2 = context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 2 } } });
+ context.ProductArticles.Add(new ProductArticle { Product = product1.Entity, OtherProduct = product2.Entity });
}
+ }
- public partial class Article
- {
- public int Id { get; set; }
- public int ProductId { get; set; }
- public bool IsDefault { get; set; }
- public short NationId { get; set; }
- public virtual Product Product { get; set; }
- }
+ class ClientContext : LocalDbContext
+ {
+ public DbSet Products { get; set; }
+ public DbSet ProductArticles { get; set; }
+ }
- public partial class Product
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public bool ECommercePublished { get; set; }
- public virtual ICollection Articles { get; set; }
- }
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
- public class PriceModel
- {
- public int Id { get; set; }
- public short RegionId { get; set; }
- public bool IsDefault { get; set; }
- }
+ await initializer.Migrate();
+ }
- public class ProductModel
- {
- public int Id { get; set; }
- public PriceModel Price { get; set; }
+ public Task DisposeAsync() => Task.CompletedTask;
+}
+
+public class MapObjectPropertyFromSubQueryWithCollection : AutoMapperSpecBase, IAsyncLifetime
+{
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection();
+ cfg.CreateProjection()
+ .ForMember(d => d.Price, o => o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault()));
+ cfg.CreateProjection()
+ .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
+ });
+
+ [Fact]
+ public void Should_cache_the_subquery()
+ {
+ using (var context = new ClientContext())
+ {
+ var projection = ProjectTo(context.ProductArticles);
+ var counter = new FirstOrDefaultCounter();
+ counter.Visit(projection.Expression);
+ counter.Count.ShouldBe(1);
+ var productModel = projection.First().Products.First();
+ productModel.Price.RegionId.ShouldBe((short)1);
+ productModel.Price.IsDefault.ShouldBeTrue();
+ productModel.Price.Id.ShouldBe(1);
+ productModel.Id.ShouldBe(1);
}
+ }
+
+ class FirstOrDefaultCounter : ExpressionVisitor
+ {
+ public int Count;
- class Initializer : DropCreateDatabaseAlways
+ protected override Expression VisitMethodCall(MethodCallExpression node)
{
- protected override void Seed(ClientContext context)
+ if (node.Method.Name == "FirstOrDefault")
{
- var product = context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
- context.ProductArticles.Add(new ProductArticle { Products = new[] { product } });
+ Count++;
}
+ return base.VisitMethodCall(node);
}
+ }
- class ClientContext : DbContext
- {
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- Database.SetInitializer(new Initializer());
- }
+ public class ProductArticle
+ {
+ public int Id { get; set; }
+ public ICollection Products { get; set; }
+ }
- public DbSet Products { get; set; }
- public DbSet ProductArticles { get; set; }
- }
+ public class ProductArticleModel
+ {
+ public int Id { get; set; }
+ public ICollection Products { get; set; }
}
- public class MapObjectPropertyFromSubQueryWithCollectionSameName : NonValidatingSpecBase
+ public partial class Article
{
- protected override MapperConfiguration CreateConfiguration() => new(cfg =>
- {
- cfg.CreateProjection();
- cfg.CreateProjection()
- .ForMember(d=>d.ArticlesModel, o=>o.MapFrom(s=>s))
- .ForMember(d => d.Articles, o => o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault()));
- cfg.CreateProjection();
- cfg.CreateProjection()
- .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
- });
-
- [Fact]
- public void Should_cache_the_subquery()
- {
- using(var context = new ClientContext())
- {
- var projection = ProjectTo(context.ProductArticles);
- var counter = new FirstOrDefaultCounter();
- counter.Visit(projection.Expression);
- counter.Count.ShouldBe(1);
- var productModel = projection.First().Products.First();
- Check(productModel.Articles);
- productModel.Id.ShouldBe(1);
- productModel.ArticlesCount.ShouldBe(1);
- productModel.ArticlesModel.Articles.Count.ShouldBe(1);
- Check(productModel.ArticlesModel.Articles.Single());
- }
- }
+ public int Id { get; set; }
+ public int ProductId { get; set; }
+ public bool IsDefault { get; set; }
+ public short NationId { get; set; }
+ public virtual Product Product { get; set; }
+ }
- private static void Check(PriceModel priceModel)
- {
- priceModel.RegionId.ShouldBe((short)1);
- priceModel.IsDefault.ShouldBeTrue();
- priceModel.Id.ShouldBe(1);
- }
+ public partial class Product
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public bool ECommercePublished { get; set; }
+ public virtual ICollection Articles { get; set; }
+ }
- class FirstOrDefaultCounter : ExpressionVisitor
- {
- public int Count;
+ public class PriceModel
+ {
+ public int Id { get; set; }
+ public short RegionId { get; set; }
+ public bool IsDefault { get; set; }
+ }
- protected override Expression VisitMethodCall(MethodCallExpression node)
- {
- if(node.Method.Name == "FirstOrDefault")
- {
- Count++;
- }
- return base.VisitMethodCall(node);
- }
- }
+ public class ProductModel
+ {
+ public int Id { get; set; }
+ public PriceModel Price { get; set; }
+ }
- public class ProductArticle
+ class DatabaseInitializer : DropCreateDatabaseAlways
+ {
+ protected override void Seed(ClientContext context)
{
- public int Id { get; set; }
- public ICollection Products { get; set; }
+ var product = context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
+ context.ProductArticles.Add(new ProductArticle { Products = new[] { product.Entity } });
}
+ }
- public class ProductArticleModel
- {
- public int Id { get; set; }
- public ICollection Products { get; set; }
- }
+ class ClientContext : LocalDbContext
+ {
+ public DbSet Products { get; set; }
+ public DbSet ProductArticles { get; set; }
+ }
- public partial class Article
- {
- public int Id { get; set; }
- public int ProductId { get; set; }
- public bool IsDefault { get; set; }
- public short NationId { get; set; }
- public virtual Product Product { get; set; }
- }
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
- public partial class Product
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public bool ECommercePublished { get; set; }
- public virtual ICollection Articles { get; set; }
- }
+ await initializer.Migrate();
+ }
- public class PriceModel
- {
- public int Id { get; set; }
- public short RegionId { get; set; }
- public bool IsDefault { get; set; }
- }
+ public Task DisposeAsync() => Task.CompletedTask;
+}
- public class ProductModel
- {
- public int Id { get; set; }
- public PriceModel Articles { get; set; }
- public int ArticlesCount { get; set; }
- public ArticlesModel ArticlesModel { get; set; }
+public class MapObjectPropertyFromSubQueryWithCollectionSameName : NonValidatingSpecBase, IAsyncLifetime
+{
+ protected override MapperConfiguration CreateConfiguration() => new(cfg =>
+ {
+ cfg.CreateProjection();
+ cfg.CreateProjection()
+ .ForMember(d => d.ArticlesModel, o => o.MapFrom(s => s))
+ .ForMember(d => d.Articles, o => o.MapFrom(source => source.Articles.Where(x => x.IsDefault && x.NationId == 1 && source.ECommercePublished).FirstOrDefault()));
+ cfg.CreateProjection();
+ cfg.CreateProjection()
+ .ForMember(d => d.RegionId, o => o.MapFrom(s => s.NationId));
+ });
+
+ [Fact]
+ public void Should_cache_the_subquery()
+ {
+ using (var context = new ClientContext())
+ {
+ var projection = ProjectTo(context.ProductArticles);
+ var counter = new FirstOrDefaultCounter();
+ counter.Visit(projection.Expression);
+ counter.Count.ShouldBe(1);
+ var productModel = projection.First().Products.First();
+ Check(productModel.Articles);
+ productModel.Id.ShouldBe(1);
+ productModel.ArticlesCount.ShouldBe(1);
+ productModel.ArticlesModel.Articles.Count.ShouldBe(1);
+ Check(productModel.ArticlesModel.Articles.Single());
}
+ }
- public class ArticlesModel
- {
- public ICollection Articles { get; set; }
- }
+ private static void Check(PriceModel priceModel)
+ {
+ priceModel.RegionId.ShouldBe((short)1);
+ priceModel.IsDefault.ShouldBeTrue();
+ priceModel.Id.ShouldBe(1);
+ }
- class Initializer : DropCreateDatabaseAlways
+ class FirstOrDefaultCounter : ExpressionVisitor
+ {
+ public int Count;
+
+ protected override Expression VisitMethodCall(MethodCallExpression node)
{
- protected override void Seed(ClientContext context)
+ if (node.Method.Name == "FirstOrDefault")
{
- var product = context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
- context.ProductArticles.Add(new ProductArticle { Products = new[] { product } });
+ Count++;
}
+ return base.VisitMethodCall(node);
}
+ }
- class ClientContext : DbContext
- {
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- Database.SetInitializer(new Initializer());
- }
+ public class ProductArticle
+ {
+ public int Id { get; set; }
+ public ICollection Products { get; set; }
+ }
- public DbSet Products { get; set; }
- public DbSet ProductArticles { get; set; }
- }
+ public class ProductArticleModel
+ {
+ public int Id { get; set; }
+ public ICollection Products { get; set; }
}
- public class SubQueryWithMapFromNullable : AutoMapperSpecBase
+ public partial class Article
{
- // Source Types
- public class Cable
- {
- public int CableId { get; set; }
- public ICollection Ends { get; set; } = new List();
- }
+ public int Id { get; set; }
+ public int ProductId { get; set; }
+ public bool IsDefault { get; set; }
+ public short NationId { get; set; }
+ public virtual Product Product { get; set; }
+ }
- public class CableEnd
- {
- [ForeignKey(nameof(CrossConnectId))]
- public virtual Cable CrossConnect { get; set; }
- [Column(Order = 0), Key]
- public int CrossConnectId { get; set; }
- [Column(Order = 1), Key]
- public string Name { get; set; }
- [ForeignKey(nameof(RackId))]
- public virtual Rack Rack { get; set; }
- public int? RackId { get; set; }
- }
+ public partial class Product
+ {
+ public int Id { get; set; }
+ public string Name { get; set; }
+ public bool ECommercePublished { get; set; }
+ public virtual ICollection Articles { get; set; }
+ }
- public class DataHall
- {
- public int DataHallId { get; set; }
- public int DataCentreId { get; set; }
- public ICollection Racks { get; set; } = new List();
- }
+ public class PriceModel
+ {
+ public int Id { get; set; }
+ public short RegionId { get; set; }
+ public bool IsDefault { get; set; }
+ }
- public class Rack
- {
- public int RackId { get; set; }
- [ForeignKey(nameof(DataHallId))]
- public virtual DataHall DataHall { get; set; }
- public int DataHallId { get; set; }
- }
+ public class ProductModel
+ {
+ public int Id { get; set; }
+ public PriceModel Articles { get; set; }
+ public int ArticlesCount { get; set; }
+ public ArticlesModel ArticlesModel { get; set; }
+ }
- // Dest Types
- public class CableListModel
- {
- public int CableId { get; set; }
- public CableEndModel AEnd { get; set; }
- public CableEndModel AnotherEnd { get; set; }
- }
+ public class ArticlesModel
+ {
+ public ICollection Articles { get; set; }
+ }
- public class CableEndModel
+ class DatabaseInitializer : DropCreateDatabaseAlways
+ {
+ protected override void Seed(ClientContext context)
{
- public string Name { get; set; }
- public int? DataHallId { get; set; }
+ var product = context.Products.Add(new Product { ECommercePublished = true, Articles = new[] { new Article { IsDefault = true, NationId = 1, ProductId = 1 } } });
+ context.ProductArticles.Add(new ProductArticle { Products = new[] { product.Entity } });
}
+ }
- class ClientContext : DbContext
- {
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- Database.SetInitializer(new Initializer());
- }
+ class ClientContext : LocalDbContext
+ {
+ public DbSet Products { get; set; }
+ public DbSet ProductArticles { get; set; }
+ }
+ public async Task InitializeAsync()
+ {
+ var initializer = new DatabaseInitializer();
+
+ await initializer.Migrate();
+ }
+
+ public Task DisposeAsync() => Task.CompletedTask;
+}
+
+public class SubQueryWithMapFromNullable : AutoMapperSpecBase, IAsyncLifetime
+{
+ // Source Types
+ public class Cable
+ {
+ public int CableId { get; set; }
+ public ICollection Ends { get; set; } = new List();
+ }
+
+ public class CableEnd
+ {
+ [ForeignKey(nameof(CrossConnectId))]
+ public virtual Cable CrossConnect { get; set; }
+ [Column(Order = 0), Key]
+ public int CrossConnectId { get; set; }
+ [Column(Order = 1), Key]
+ public string Name { get; set; }
+ [ForeignKey(nameof(RackId))]
+ public virtual Rack Rack { get; set; }
+ public int? RackId { get; set; }
+ }
+
+ public class DataHall
+ {
+ public int DataHallId { get; set; }
+ public int DataCentreId { get; set; }
+ public ICollection Racks { get; set; } = new List();
+ }
+
+ public class Rack
+ {
+ public int RackId { get; set; }
+ [ForeignKey(nameof(DataHallId))]
+ public virtual DataHall DataHall { get; set; }
+ public int DataHallId { get; set; }
+ }
+
+ // Dest Types
+ public class CableListModel
+ {
+ public int CableId { get; set; }
+ public CableEndModel AEnd { get; set; }
+ public CableEndModel AnotherEnd { get; set; }
+ }
- public DbSet Cables { get; set; }
- public DbSet