Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query: Add TPC test bases #27946

Merged
merged 1 commit into from
May 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// ReSharper disable InconsistentNaming

namespace Microsoft.EntityFrameworkCore.Query;

public abstract class TPCFiltersInheritanceQueryTestBase<TFixture> : FiltersInheritanceQueryTestBase<TFixture>
where TFixture : TPCInheritanceQueryFixture, new()
{
public TPCFiltersInheritanceQueryTestBase(TFixture fixture)
: base(fixture)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.EntityFrameworkCore.TestModels.GearsOfWarModel;

namespace Microsoft.EntityFrameworkCore.Query;

public abstract class TPCGearsOfWarQueryRelationalFixture : GearsOfWarQueryFixtureBase
{
protected override string StoreName { get; } = "TPCGearsOfWarQueryTest";

public new RelationalTestStore TestStore
=> (RelationalTestStore)base.TestStore;

public TestSqlLoggerFactory TestSqlLoggerFactory
=> (TestSqlLoggerFactory)ListLoggerFactory;

protected override bool ShouldLogCategory(string logCategory)
=> logCategory == DbLoggerCategory.Query.Name;

public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
=> base.AddOptions(builder).ConfigureWarnings(
w =>
w.Log(RelationalEventId.ForeignKeyTpcPrincipalWarning));

protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
{
base.OnModelCreating(modelBuilder, context);

modelBuilder.Entity<Gear>().UseTpcMappingStrategy();
modelBuilder.Entity<Faction>().UseTpcMappingStrategy();
modelBuilder.Entity<LocustLeader>().UseTpcMappingStrategy();

// Work-around for issue#27947
modelBuilder.Entity<Faction>().ToTable((string)null);

modelBuilder.Entity<Gear>().ToTable("Gears");
modelBuilder.Entity<Officer>().ToTable("Officers");

modelBuilder.Entity<LocustHorde>().ToTable("LocustHordes");

modelBuilder.Entity<LocustLeader>().ToTable("LocustLeaders");
modelBuilder.Entity<LocustCommander>().ToTable("LocustCommanders");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.EntityFrameworkCore.Query;

public abstract class TPCGearsOfWarQueryRelationalTestBase<TFixture> : GearsOfWarQueryRelationalTestBase<TFixture>
where TFixture : TPCGearsOfWarQueryRelationalFixture, new()
{
protected TPCGearsOfWarQueryRelationalTestBase(TFixture fixture)
: base(fixture)
{
}

public override Task Project_discriminator_columns(bool async)
=> AssertUnableToTranslateEFProperty(() => base.Project_discriminator_columns(async));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.EntityFrameworkCore.TestModels.InheritanceModel;

namespace Microsoft.EntityFrameworkCore.Query;

public abstract class TPCInheritanceQueryFixture : InheritanceQueryFixtureBase
{
protected override string StoreName
=> "TPCInheritanceTest";

public TestSqlLoggerFactory TestSqlLoggerFactory
=> (TestSqlLoggerFactory)ListLoggerFactory;

protected override bool HasDiscriminator
=> false;

protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
{
base.OnModelCreating(modelBuilder, context);

// Configure TPT for hierarchies
modelBuilder.Entity<Plant>().UseTpcMappingStrategy();
modelBuilder.Entity<Animal>().UseTpcMappingStrategy();
modelBuilder.Entity<Drink>().UseTpcMappingStrategy();

// Work-around for issue#27947
modelBuilder.Entity<Animal>().ToTable((string)null);
modelBuilder.Entity<Plant>().ToTable((string)null);

modelBuilder.Entity<Flower>().ToTable("Flowers");
modelBuilder.Entity<Rose>().ToTable("Roses");
modelBuilder.Entity<Daisy>().ToTable("Daisies");
modelBuilder.Entity<Country>().Property(e => e.Id).ValueGeneratedNever();

modelBuilder.Entity<Bird>().ToTable("Birds");
modelBuilder.Entity<Eagle>().ToTable("Eagle");
modelBuilder.Entity<Kiwi>().ToTable("Kiwi");
modelBuilder.Entity<Animal>().Property(e => e.Species).HasMaxLength(100);
modelBuilder.Entity<Eagle>().HasMany(e => e.Prey).WithOne().HasForeignKey(e => e.EagleId).IsRequired(false);

modelBuilder.Entity<Drink>().ToTable("Drinks");
modelBuilder.Entity<Coke>().ToTable("Coke");
modelBuilder.Entity<Lilt>().ToTable("Lilt");
modelBuilder.Entity<Tea>().ToTable("Tea");

modelBuilder.Entity<Coke>().Property(e => e.Carbonation).HasColumnName("CokeCO2");
modelBuilder.Entity<Coke>().Property(e => e.SugarGrams).HasColumnName("SugarGrams");
modelBuilder.Entity<Coke>().Property(e => e.CaffeineGrams).HasColumnName("CaffeineGrams");
modelBuilder.Entity<Lilt>().Property(e => e.Carbonation).HasColumnName("LiltCO2");
modelBuilder.Entity<Lilt>().Property(e => e.SugarGrams).HasColumnName("SugarGrams");
modelBuilder.Entity<Tea>().Property(e => e.CaffeineGrams).HasColumnName("CaffeineGrams");

// Keyless entities are mapped to TPH so ignoring them
modelBuilder.Ignore<AnimalQuery>();
modelBuilder.Ignore<BirdQuery>();
modelBuilder.Ignore<KiwiQuery>();
modelBuilder.Ignore<EagleQuery>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// ReSharper disable InconsistentNaming

using Microsoft.EntityFrameworkCore.TestModels.InheritanceModel;

namespace Microsoft.EntityFrameworkCore.Query;

public abstract class TPCInheritanceQueryTestBase<TFixture> : InheritanceQueryTestBase<TFixture>
where TFixture : TPCInheritanceQueryFixture, new()
{
public TPCInheritanceQueryTestBase(TFixture fixture)
: base(fixture)
{
}

// Keyless entities does not have TPC
public override Task Can_query_all_animal_views(bool async)
=> Task.CompletedTask;

// TPC does not have discriminator
public override Task Discriminator_used_when_projection_over_derived_type(bool async)
=> Task.CompletedTask;

// TPC does not have discriminator
public override Task Discriminator_used_when_projection_over_derived_type2(bool async)
=> Task.CompletedTask;

// TPC does not have discriminator
public override Task Discriminator_used_when_projection_over_of_type(bool async)
=> Task.CompletedTask;

// TPC does not have discriminator
public override Task Discriminator_with_cast_in_shadow_property(bool async)
=> Task.CompletedTask;

[ConditionalFact]
public virtual void Using_from_sql_throws()
{
using var context = CreateContext();

var message = Assert.Throws<InvalidOperationException>(() => context.Set<Bird>().FromSqlRaw("Select * from Birds")).Message;

Assert.Equal(RelationalStrings.MethodOnNonTphRootNotSupported("FromSqlRaw", typeof(Bird).Name), message);

message = Assert.Throws<InvalidOperationException>(() => context.Set<Bird>().FromSqlInterpolated($"Select * from Birds"))
.Message;

Assert.Equal(RelationalStrings.MethodOnNonTphRootNotSupported("FromSqlInterpolated", typeof(Bird).Name), message);
}

protected override void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction)
=> facade.UseTransaction(transaction.GetDbTransaction());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.EntityFrameworkCore.Query;

public abstract class TPCManyToManyNoTrackingQueryRelationalTestBase<TFixture> : ManyToManyNoTrackingQueryRelationalTestBase<TFixture>
where TFixture : TPCManyToManyQueryRelationalFixture, new()
{
protected TPCManyToManyNoTrackingQueryRelationalTestBase(TFixture fixture)
: base(fixture)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.EntityFrameworkCore.TestModels.ManyToManyModel;

namespace Microsoft.EntityFrameworkCore.Query;

public abstract class TPCManyToManyQueryRelationalFixture : ManyToManyQueryRelationalFixture
{
protected override string StoreName { get; } = "TPCManyToManyQueryTest";

public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
=> base.AddOptions(builder).ConfigureWarnings(
w =>
w.Log(RelationalEventId.ForeignKeyTpcPrincipalWarning));

protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
{
base.OnModelCreating(modelBuilder, context);

modelBuilder.Entity<EntityRoot>().UseTpcMappingStrategy();

modelBuilder.Entity<EntityRoot>().ToTable("Roots");
modelBuilder.Entity<EntityBranch>().ToTable("Branches");
modelBuilder.Entity<EntityLeaf>().ToTable("Leaves");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Microsoft.EntityFrameworkCore.Query;

public abstract class TPCManyToManyQueryRelationalTestBase<TFixture> : ManyToManyQueryRelationalTestBase<TFixture>
where TFixture : TPCManyToManyQueryRelationalFixture, new()
{
protected TPCManyToManyQueryRelationalTestBase(TFixture fixture)
: base(fixture)
{
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.EntityFrameworkCore.TestModels.InheritanceRelationshipsModel;

namespace Microsoft.EntityFrameworkCore.Query;

public abstract class TPCRelationshipsQueryRelationalFixture : InheritanceRelationshipsQueryRelationalFixture
{
protected override string StoreName { get; } = "TPCRelationships";

public override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder builder)
=> base.AddOptions(builder).ConfigureWarnings(
w =>
w.Log(RelationalEventId.ForeignKeyTpcPrincipalWarning));

protected override void OnModelCreating(ModelBuilder modelBuilder, DbContext context)
{
base.OnModelCreating(modelBuilder, context);

modelBuilder.Entity<BaseInheritanceRelationshipEntity>().UseTpcMappingStrategy();
modelBuilder.Entity<BaseReferenceOnBase>().UseTpcMappingStrategy();
modelBuilder.Entity<BaseCollectionOnBase>().UseTpcMappingStrategy();
modelBuilder.Entity<BaseReferenceOnDerived>().UseTpcMappingStrategy();
modelBuilder.Entity<BaseCollectionOnDerived>().UseTpcMappingStrategy();
modelBuilder.Entity<NestedReferenceBase>().UseTpcMappingStrategy();
modelBuilder.Entity<NestedCollectionBase>().UseTpcMappingStrategy();

modelBuilder.Entity<DerivedInheritanceRelationshipEntity>().ToTable("DerivedEntities");

modelBuilder.Entity<DerivedReferenceOnBase>().ToTable("DerivedReferencesOnBase");
modelBuilder.Entity<DerivedCollectionOnBase>().ToTable("DerivedCollectionsOnBase");
modelBuilder.Entity<DerivedReferenceOnDerived>().ToTable("DerivedReferencesOnDerived");
modelBuilder.Entity<DerivedCollectionOnDerived>().ToTable("DerivedCollectionsOnDerived");

modelBuilder.Entity<NestedReferenceDerived>().ToTable("NestedReferencesDerived");
modelBuilder.Entity<NestedCollectionDerived>().ToTable("NestedCollectionsDerived");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// ReSharper disable InconsistentNaming

namespace Microsoft.EntityFrameworkCore.Query;

public abstract class TPCRelationshipsQueryTestBase<TFixture> : InheritanceRelationshipsQueryRelationalTestBase<TFixture>
where TFixture : TPCRelationshipsQueryRelationalFixture, new()
{
protected TPCRelationshipsQueryTestBase(TFixture fixture)
: base(fixture)
{
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ void RewriteSourceWithNewBaseline(string fileName, int lineNumber)
indentBuilder.Append(" ");
var indent = indentBuilder.ToString();
var newBaseLine = $@"AssertSql(
{indent}{string.Join(",\n" + indent + "//\n" + indent, SqlStatements.Select(sql => "@\"" + sql.Replace("\"", "\"\"") + "\""))})";
{indent}{string.Join("," + Environment.NewLine + indent + "//" + Environment.NewLine + indent, SqlStatements.Select(sql => "@\"" + sql.Replace("\"", "\"\"") + "\""))})";
var numNewlinesInRewritten = newBaseLine.Count(c => c is '\n' or '\r');

writer.Write(newBaseLine);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ public FiltersInheritanceQuerySqlServerTest(FiltersInheritanceQuerySqlServerFixt
//Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper);
}

[ConditionalFact]
public virtual void Check_all_tests_overridden()
=> TestHelpers.AssertAllMethodsOverridden(GetType());

public override async Task Can_use_of_type_animal(bool async)
{
await base.Can_use_of_type_animal(async);
Expand Down Expand Up @@ -119,6 +123,22 @@ FROM [Animals] AS [a]
WHERE [a].[Discriminator] = N'Eagle' AND [a].[CountryId] = 1");
}

public override async Task Can_use_IgnoreQueryFilters_and_GetDatabaseValues(bool async)
{
await base.Can_use_IgnoreQueryFilters_and_GetDatabaseValues(async);

AssertSql(
@"SELECT TOP(2) [a].[Species], [a].[CountryId], [a].[Discriminator], [a].[Name], [a].[EagleId], [a].[IsFlightless], [a].[Group]
FROM [Animals] AS [a]
WHERE [a].[Discriminator] = N'Eagle'",
//
@"@__p_0='Aquila chrysaetos canadensis' (Size = 100)

SELECT TOP(1) [a].[Species], [a].[CountryId], [a].[Discriminator], [a].[Name], [a].[EagleId], [a].[IsFlightless], [a].[Group]
FROM [Animals] AS [a]
WHERE [a].[Discriminator] = N'Eagle' AND [a].[Species] = @__p_0");
}

private void AssertSql(params string[] expected)
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
}
Loading