Skip to content

Commit

Permalink
Create a provider agnostic test base to put custom models (#24737)
Browse files Browse the repository at this point in the history
We can move tests out of QueryBugsTest at some point

Resolves #20277
  • Loading branch information
smitpatel authored Apr 23, 2021
1 parent c734abc commit 682ccb2
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.EntityFrameworkCore.TestUtilities;

namespace Microsoft.EntityFrameworkCore.Query
{
public class OwnedEntityQueryInMemoryTest : OwnedEntityQueryTestBase
{
protected override ITestStoreFactory TestStoreFactory => InMemoryTestStoreFactory.Instance;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.EntityFrameworkCore.TestUtilities;

namespace Microsoft.EntityFrameworkCore.Query
{
public abstract class OwnedEntityQueryRelationalTestBase : OwnedEntityQueryTestBase
{
protected TestSqlLoggerFactory TestSqlLoggerFactory
=> (TestSqlLoggerFactory)ListLoggerFactory;

protected void ClearLog() => TestSqlLoggerFactory.Clear();

protected void AssertSql(params string[] expected) => TestSqlLoggerFactory.AssertBaseline(expected);
}
}
94 changes: 94 additions & 0 deletions test/EFCore.Specification.Tests/Query/OwnedEntityQueryTestBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Xunit;

namespace Microsoft.EntityFrameworkCore
{
public abstract class OwnedEntityQueryTestBase : NonSharedModelTestBase
{
public static IEnumerable<object[]> IsAsyncData = new[] { new object[] { false }, new object[] { true } };

protected override string StoreName => "OwnedEntityQueryTests";

[ConditionalTheory]
[MemberData(nameof(IsAsyncData))]
public virtual async Task Multiple_single_result_in_projection_containing_owned_types(bool async)
{
var contextFactory = await InitializeAsync<Context20277>();

using (var context = contextFactory.CreateContext())
{
await context.Entities.AsNoTracking().Select(e => new
{
Id = e.Id,
FirstChild = e.Children
.Where(c => c.Type == 1)
.AsQueryable()
.Select(_project)
.FirstOrDefault(),
SecondChild = e.Children
.Where(c => c.Type == 2)
.AsQueryable()
.Select(_project)
.FirstOrDefault(),
}).ToListAsync();
}
}

private static readonly Expression<Func<Child20277, object>> _project = x => new
{
x.Id,
x.Owned, // Comment this line for success
x.Type,
};

protected class Context20277 : DbContext
{
public Context20277(DbContextOptions options)
: base(options)
{
}

public DbSet<Entity20277> Entities => Set<Entity20277>();

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

modelBuilder.Entity<Entity20277>(cfg =>
{
cfg.OwnsMany(e => e.Children, inner =>
{
inner.OwnsOne(e => e.Owned);
});
});
}
}

protected class Entity20277
{
public int Id { get; set; }
public List<Child20277> Children { get; set; }
}

protected class Child20277
{
public int Id { get; set; }
public int Type { get; set; }
public Owned20277 Owned { get; set; }
}

protected class Owned20277
{
public bool IsDeleted { get; set; }
public string Value { get; set; }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore.TestUtilities;

// ReSharper disable InconsistentNaming
namespace Microsoft.EntityFrameworkCore.Query
{
public class OwnedEntityQuerySqlServerTest : OwnedEntityQueryRelationalTestBase
{
protected override ITestStoreFactory TestStoreFactory => SqlServerTestStoreFactory.Instance;

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

AssertSql(
@"SELECT [e].[Id], [t0].[Id], [t0].[Entity20277Id], [t0].[Owned_IsDeleted], [t0].[Owned_Value], [t0].[Type], [t0].[c], [t1].[Id], [t1].[Entity20277Id], [t1].[Owned_IsDeleted], [t1].[Owned_Value], [t1].[Type], [t1].[c]
FROM [Entities] AS [e]
LEFT JOIN (
SELECT [t].[Id], [t].[Entity20277Id], [t].[Owned_IsDeleted], [t].[Owned_Value], [t].[Type], [t].[c]
FROM (
SELECT [c].[Id], [c].[Entity20277Id], [c].[Owned_IsDeleted], [c].[Owned_Value], [c].[Type], 1 AS [c], ROW_NUMBER() OVER(PARTITION BY [c].[Entity20277Id] ORDER BY [c].[Entity20277Id], [c].[Id]) AS [row]
FROM [Child20277] AS [c]
WHERE [c].[Type] = 1
) AS [t]
WHERE [t].[row] <= 1
) AS [t0] ON [e].[Id] = [t0].[Entity20277Id]
LEFT JOIN (
SELECT [t2].[Id], [t2].[Entity20277Id], [t2].[Owned_IsDeleted], [t2].[Owned_Value], [t2].[Type], [t2].[c]
FROM (
SELECT [c0].[Id], [c0].[Entity20277Id], [c0].[Owned_IsDeleted], [c0].[Owned_Value], [c0].[Type], 1 AS [c], ROW_NUMBER() OVER(PARTITION BY [c0].[Entity20277Id] ORDER BY [c0].[Entity20277Id], [c0].[Id]) AS [row]
FROM [Child20277] AS [c0]
WHERE [c0].[Type] = 2
) AS [t2]
WHERE [t2].[row] <= 1
) AS [t1] ON [e].[Id] = [t1].[Entity20277Id]");
}
}
}
4 changes: 2 additions & 2 deletions test/EFCore.SqlServer.FunctionalTests/Query/QueryBugsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10115,7 +10115,7 @@ protected override DbContextOptionsBuilder AddOptions(DbContextOptionsBuilder bu
protected override TestStore CreateTestStore()
=> SqlServerTestStore.CreateInitialized(StoreName, multipleActiveResultSets: true);

private static readonly FieldInfo querySplittingBehaviorFieldInfo =
private static readonly FieldInfo _querySplittingBehaviorFieldInfo =
typeof(RelationalOptionsExtension).GetField("_querySplittingBehavior", BindingFlags.NonPublic | BindingFlags.Instance);

protected DbContextOptionsBuilder ClearQuerySplittingBehavior(DbContextOptionsBuilder optionsBuilder)
Expand All @@ -10127,7 +10127,7 @@ protected DbContextOptionsBuilder ClearQuerySplittingBehavior(DbContextOptionsBu
}
else
{
querySplittingBehaviorFieldInfo.SetValue(extension, null);
_querySplittingBehaviorFieldInfo.SetValue(extension, null);
}

((IDbContextOptionsBuilderInfrastructure)optionsBuilder).AddOrUpdateExtension(extension);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using Microsoft.EntityFrameworkCore.TestUtilities;

namespace Microsoft.EntityFrameworkCore.Query
{
public class OwnedEntityQuerySqliteTest : OwnedEntityQueryRelationalTestBase
{
protected override ITestStoreFactory TestStoreFactory
=> SqliteTestStoreFactory.Instance;
}
}

0 comments on commit 682ccb2

Please sign in to comment.