-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test for entity type with navigation mapped to SqlQuery (#28990)
- Loading branch information
1 parent
17ea4d0
commit d67de27
Showing
3 changed files
with
188 additions
and
0 deletions.
There are no files selected for viewing
130 changes: 130 additions & 0 deletions
130
test/EFCore.Relational.Specification.Tests/Query/ToSqlQueryTestBase.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
#nullable enable | ||
|
||
namespace Microsoft.EntityFrameworkCore.Query; | ||
|
||
public abstract class ToSqlQueryTestBase : NonSharedModelTestBase | ||
{ | ||
protected override string StoreName | ||
=> "ToSqlQueryTests"; | ||
|
||
[ConditionalTheory] | ||
[MemberData(nameof(IsAsyncData))] // Issue #27629 | ||
public virtual async Task Entity_type_with_navigation_mapped_to_SqlQuery(bool async) | ||
{ | ||
var contextFactory = await InitializeAsync<Context27629>(seed: c => | ||
{ | ||
var author = new Author { Name = "Toast", Posts = { new() { Title = "Sausages of the world!"} } }; | ||
c.Add(author); | ||
c.SaveChanges(); | ||
var postStat = new PostStat { Count = 10, Author = author }; | ||
author.PostStat = postStat; | ||
c.Add(postStat); | ||
c.SaveChanges(); | ||
}); | ||
|
||
using var context = contextFactory.CreateContext(); | ||
|
||
var authors = await | ||
(from o in context.Authors | ||
select new | ||
{ | ||
Author = o, | ||
PostCount = o.PostStat!.Count | ||
}).ToListAsync(); | ||
|
||
Assert.Single(authors); | ||
Assert.Equal("Toast", authors[0].Author.Name); | ||
Assert.Equal(10, authors[0].PostCount); | ||
} | ||
|
||
protected class Context27629 : DbContext | ||
{ | ||
public Context27629(DbContextOptions options) | ||
: base(options) | ||
{ | ||
} | ||
|
||
public DbSet<Author> Authors | ||
=> Set<Author>(); | ||
|
||
public DbSet<Post> Posts | ||
=> Set<Post>(); | ||
|
||
public DbSet<PostStat> PostStats | ||
=> Set<PostStat>(); | ||
|
||
protected override void OnModelCreating(ModelBuilder modelBuilder) | ||
{ | ||
modelBuilder.Entity<Author>( | ||
builder => | ||
{ | ||
builder.ToTable("Authors"); | ||
builder.Property(o => o.Name).HasMaxLength(50); | ||
}); | ||
|
||
modelBuilder.Entity<Post>( | ||
builder => | ||
{ | ||
builder.ToTable("Posts"); | ||
builder.Property(o => o.Title).HasMaxLength(50); | ||
builder.Property(o => o.Content).HasMaxLength(500); | ||
builder | ||
.HasOne(o => o.Author) | ||
.WithMany(o => o.Posts) | ||
.HasForeignKey(o => o.AuthorId) | ||
.OnDelete(DeleteBehavior.ClientCascade); | ||
}); | ||
|
||
modelBuilder.Entity<PostStat>( | ||
builder => | ||
{ | ||
builder | ||
.ToSqlQuery("SELECT * FROM PostStats") | ||
.HasKey(o => o.AuthorId); | ||
builder | ||
.HasOne(o => o.Author) | ||
.WithOne().HasForeignKey<PostStat>(o => o.AuthorId) | ||
.OnDelete(DeleteBehavior.ClientCascade); | ||
}); | ||
} | ||
} | ||
|
||
protected class Author | ||
{ | ||
public long Id { get; set; } | ||
public string Name { get; set; } = null!; | ||
public List<Post> Posts { get; } = new(); | ||
public PostStat? PostStat { get; set; } | ||
} | ||
|
||
protected class Post | ||
{ | ||
public long Id { get; set; } | ||
public long AuthorId { get; set; } | ||
public Author Author { get; set; } = null!; | ||
public string? Title { get; set; } | ||
public string? Content { get; set; } | ||
} | ||
|
||
protected class PostStat | ||
{ | ||
public long AuthorId { get; set; } | ||
public Author Author { get; set; } = null!; | ||
public long? Count { get; set; } | ||
} | ||
|
||
public void UseTransaction(DatabaseFacade facade, IDbContextTransaction transaction) | ||
=> facade.UseTransaction(transaction.GetDbTransaction()); | ||
|
||
protected TestSqlLoggerFactory TestSqlLoggerFactory | ||
=> (TestSqlLoggerFactory)ListLoggerFactory; | ||
|
||
protected void ClearLog() | ||
=> TestSqlLoggerFactory.Clear(); | ||
} |
29 changes: 29 additions & 0 deletions
29
test/EFCore.SqlServer.FunctionalTests/Query/ToSqlQuerySqlServerTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// 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 class ToSqlQuerySqlServerTest : ToSqlQueryTestBase | ||
{ | ||
protected override ITestStoreFactory TestStoreFactory | ||
=> SqlServerTestStoreFactory.Instance; | ||
|
||
[ConditionalFact] | ||
public virtual void Check_all_tests_overridden() | ||
=> TestHelpers.AssertAllMethodsOverridden(GetType()); | ||
|
||
public override async Task Entity_type_with_navigation_mapped_to_SqlQuery(bool async) | ||
{ | ||
await base.Entity_type_with_navigation_mapped_to_SqlQuery(async); | ||
|
||
AssertSql( | ||
@"SELECT [a].[Id], [a].[Name], [a].[PostStatAuthorId], [m].[Count] AS [PostCount] | ||
FROM [Authors] AS [a] | ||
LEFT JOIN ( | ||
SELECT * FROM PostStats | ||
) AS [m] ON [a].[PostStatAuthorId] = [m].[AuthorId]"); | ||
} | ||
|
||
private void AssertSql(params string[] expected) | ||
=> TestSqlLoggerFactory.AssertBaseline(expected); | ||
} |
29 changes: 29 additions & 0 deletions
29
test/EFCore.Sqlite.FunctionalTests/Query/ToSqlQuerySqliteTest.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// 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 class ToSqlQuerySqliteTest : ToSqlQueryTestBase | ||
{ | ||
protected override ITestStoreFactory TestStoreFactory | ||
=> SqliteTestStoreFactory.Instance; | ||
|
||
[ConditionalFact] | ||
public virtual void Check_all_tests_overridden() | ||
=> TestHelpers.AssertAllMethodsOverridden(GetType()); | ||
|
||
public override async Task Entity_type_with_navigation_mapped_to_SqlQuery(bool async) | ||
{ | ||
await base.Entity_type_with_navigation_mapped_to_SqlQuery(async); | ||
|
||
AssertSql( | ||
@"SELECT ""a"".""Id"", ""a"".""Name"", ""a"".""PostStatAuthorId"", ""m"".""Count"" AS ""PostCount"" | ||
FROM ""Authors"" AS ""a"" | ||
LEFT JOIN ( | ||
SELECT * FROM PostStats | ||
) AS ""m"" ON ""a"".""PostStatAuthorId"" = ""m"".""AuthorId"""); | ||
} | ||
|
||
private void AssertSql(params string[] expected) | ||
=> TestSqlLoggerFactory.AssertBaseline(expected); | ||
} |