diff --git a/src/Directory.Build.props b/src/Directory.Build.props index f698cc43..03c5aef6 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -2,7 +2,7 @@ CS1591;CS0649;CS8632;EF1001 - 12.4.0 + 13.0.0 preview 1.0.0 EntityFramework, Verify diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props index 9d03b39a..696bc891 100644 --- a/src/Directory.Packages.props +++ b/src/Directory.Packages.props @@ -4,25 +4,25 @@ true - - + + - - - - - - + + + + + + - + - + \ No newline at end of file diff --git a/src/Verify.EntityFramework.Tests/GlobalUsings.cs b/src/Verify.EntityFramework.Tests/GlobalUsings.cs index 1500c34e..54e983d6 100644 --- a/src/Verify.EntityFramework.Tests/GlobalUsings.cs +++ b/src/Verify.EntityFramework.Tests/GlobalUsings.cs @@ -7,5 +7,4 @@ global using Microsoft.Data.Sqlite; global using Microsoft.EntityFrameworkCore; global using Microsoft.Extensions.DependencyInjection; -global using Microsoft.Extensions.Hosting; -global using VerifyTests.EntityFramework; \ No newline at end of file +global using Microsoft.Extensions.Hosting; \ No newline at end of file diff --git a/src/Verify.EntityFramework.Tests/Snippets/DataContext/SampleDbContext.cs b/src/Verify.EntityFramework.Tests/Snippets/DataContext/SampleDbContext.cs index 25f38953..460266c8 100644 --- a/src/Verify.EntityFramework.Tests/Snippets/DataContext/SampleDbContext.cs +++ b/src/Verify.EntityFramework.Tests/Snippets/DataContext/SampleDbContext.cs @@ -4,13 +4,13 @@ public DbSet Employees { get; set; } = null!; public DbSet Companies { get; set; } = null!; - protected override void OnModelCreating(ModelBuilder builder) + protected override void OnModelCreating(ModelBuilder model) { - builder + model .Entity() .HasMany(_ => _.Employees) .WithOne(_ => _.Company) .IsRequired(); - builder.Entity(); + model.Entity(); } } \ No newline at end of file diff --git a/src/Verify.EntityFramework/Extensions.cs b/src/Verify.EntityFramework/Extensions.cs index c7f1d9d2..223a6c6b 100644 --- a/src/Verify.EntityFramework/Extensions.cs +++ b/src/Verify.EntityFramework/Extensions.cs @@ -11,6 +11,21 @@ public static IQueryable AsNoTracking(this IQueryable set, Type return (IQueryable) genericNoTracking.Invoke(null, [set])!; } + public static string? NameOrAlias(this TableExpressionBase tableExpressionBase) + { + if (tableExpressionBase.Alias != null) + { + return tableExpressionBase.Alias; + } + + if (tableExpressionBase is TableExpression tableExpression) + { + return tableExpression.Name; + } + + return null; + } + public static IQueryable Set(this DbContext data, Type t) => (IQueryable) setMethod .MakeGenericMethod(t) diff --git a/src/Verify.EntityFramework/LogCommandInterceptor.cs b/src/Verify.EntityFramework/LogCommandInterceptor.cs index 4324fa81..58afc7e4 100644 --- a/src/Verify.EntityFramework/LogCommandInterceptor.cs +++ b/src/Verify.EntityFramework/LogCommandInterceptor.cs @@ -49,7 +49,8 @@ public override ValueTask NonQueryExecutedAsync(DbCommand command, CommandE void Add(string type, DbCommand command, CommandEndEventData data, Exception? exception = null) { var context = data.Context; - if (context != null && context.IsRecordingDisabled()) + if (context != null && + context.IsRecordingDisabled()) { return; } diff --git a/src/Verify.EntityFramework/MissingOrder/MissingOrderByVisitor.cs b/src/Verify.EntityFramework/MissingOrder/MissingOrderByVisitor.cs index a0909ca8..4ab0d25b 100644 --- a/src/Verify.EntityFramework/MissingOrder/MissingOrderByVisitor.cs +++ b/src/Verify.EntityFramework/MissingOrder/MissingOrderByVisitor.cs @@ -1,6 +1,7 @@ -sealed class MissingOrderByVisitor : ExpressionVisitor +sealed class MissingOrderByVisitor : + ExpressionVisitor { - List orderedExpressions = []; + List orderedTables = []; public override Expression? Visit(Expression? expression) { @@ -11,41 +12,38 @@ switch (expression) { - case ShapedQueryExpression shapedQueryExpression: - if(shapedQueryExpression.ResultCardinality != ResultCardinality.Enumerable) + case ShapedQueryExpression shaped: + if(shaped.ResultCardinality != ResultCardinality.Enumerable) { return null; } - Visit(shapedQueryExpression.QueryExpression); - return shapedQueryExpression; + Visit(shaped.QueryExpression); + return shaped; - case RelationalSplitCollectionShaperExpression splitExpression: - foreach (var table in splitExpression.SelectExpression.Tables) + case RelationalSplitCollectionShaperExpression split: + foreach (var table in split.SelectExpression.Tables) { Visit(table); } - Visit(splitExpression.InnerShaper); + Visit(split.InnerShaper); - return splitExpression; + return split; case TableExpression tableExpression: { - foreach (var orderedExpression in orderedExpressions) + foreach (var table in orderedTables) { - if (orderedExpression.Expression is ColumnExpression columnExpression) + if (table == tableExpression) { - if (columnExpression.TableAlias == tableExpression.Name) - { - return base.Visit(expression); - } + return base.Visit(expression); + } - if (columnExpression.Table is PredicateJoinExpressionBase joinExpression) + if (table is PredicateJoinExpressionBase join) + { + if (join.Table == tableExpression) { - if (joinExpression.Table == tableExpression) - { - return base.Visit(expression); - } + return base.Visit(expression); } } } @@ -57,22 +55,32 @@ TableExpression must have at least one ordering. {ExpressionPrinter.Print(tableExpression)} """); } - case SelectExpression selectExpression: + case SelectExpression select: { - var orderings = selectExpression.Orderings; + var orderings = select.Orderings; if (orderings.Count == 0) { throw new( $""" SelectExpression must have at least one ordering. Expression: - {PrintShortSql(selectExpression)} + {PrintShortSql(select)} """); } foreach (var ordering in orderings) { - orderedExpressions.Add(ordering); + if (ordering.Expression is not ColumnExpression column) + { + continue; + } + + if (!TryFindTable(select.Tables, column.TableAlias, out var table)) + { + continue; + } + + orderedTables.Add(table); } return base.Visit(expression); @@ -86,6 +94,28 @@ SelectExpression must have at least one ordering. } } + static bool TryFindTable(IReadOnlyList tables, string name, [NotNullWhen(true)] out TableExpressionBase? result) + { + foreach (var table in tables) + { + if (table.NameOrAlias() == name) + { + result = table; + return true; + } + + if (table is LeftJoinExpression join && + join.Table.NameOrAlias() == name) + { + result = join; + return true; + } + } + + result = null; + return false; + } + [UnsafeAccessor(UnsafeAccessorKind.Method, Name = "PrintShortSql")] static extern string PrintShortSql(SelectExpression expression); } \ No newline at end of file diff --git a/src/Verify.EntityFramework/MissingOrder/RelationalFactory.cs b/src/Verify.EntityFramework/MissingOrder/RelationalFactory.cs index e3836659..9c42ac8c 100644 --- a/src/Verify.EntityFramework/MissingOrder/RelationalFactory.cs +++ b/src/Verify.EntityFramework/MissingOrder/RelationalFactory.cs @@ -1,11 +1,9 @@ -class RelationalFactory : RelationalShapedQueryCompilingExpressionVisitorFactory +class RelationalFactory( + ShapedQueryCompilingExpressionVisitorDependencies dependencies, + RelationalShapedQueryCompilingExpressionVisitorDependencies relational) : + RelationalShapedQueryCompilingExpressionVisitorFactory(dependencies, relational) { - public RelationalFactory(ShapedQueryCompilingExpressionVisitorDependencies dependencies, RelationalShapedQueryCompilingExpressionVisitorDependencies relationalDependencies) : - base(dependencies, relationalDependencies) - { - } - - public override ShapedQueryCompilingExpressionVisitor Create(QueryCompilationContext context) + public override ShapedQueryCompilingExpressionVisitor Create(QueryCompilationContext context) => new RelationalVisitor( Dependencies, RelationalDependencies, diff --git a/src/Verify.EntityFramework/MissingOrder/RelationalVisitor.cs b/src/Verify.EntityFramework/MissingOrder/RelationalVisitor.cs index c8f63044..c4c81adb 100644 --- a/src/Verify.EntityFramework/MissingOrder/RelationalVisitor.cs +++ b/src/Verify.EntityFramework/MissingOrder/RelationalVisitor.cs @@ -1,12 +1,10 @@ -class RelationalVisitor : - RelationalShapedQueryCompilingExpressionVisitor +class RelationalVisitor( + ShapedQueryCompilingExpressionVisitorDependencies dependencies, + RelationalShapedQueryCompilingExpressionVisitorDependencies relational, + QueryCompilationContext context) : + RelationalShapedQueryCompilingExpressionVisitor(dependencies, relational, context) { - public RelationalVisitor(ShapedQueryCompilingExpressionVisitorDependencies dependencies, RelationalShapedQueryCompilingExpressionVisitorDependencies relationalDependencies, QueryCompilationContext context) : - base(dependencies, relationalDependencies, context) - { - } - - [return: NotNullIfNotNull("node")] + [return: NotNullIfNotNull(nameof(node))] public override Expression? Visit(Expression? node) { new MissingOrderByVisitor().Visit(node); diff --git a/src/Verify.EntityFramework/SqlRecording.cs b/src/Verify.EntityFramework/SqlRecording.cs deleted file mode 100644 index 1b4a167c..00000000 --- a/src/Verify.EntityFramework/SqlRecording.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace VerifyTests.EntityFramework; - -[Obsolete("Use VerifyTest.Recording", true)] -public static class EfRecording -{ - [Obsolete("Use VerifyTest.Recording.Start()", true)] - public static void StartRecording() - { - } - - [Obsolete("Use VerifyTest.Recording.Start(string identifier)", true)] - public static void StartRecording(string identifier) - { - } - - [Obsolete("Use VerifyTest.Recording.Stop()", true)] - public static IReadOnlyList FinishRecording() => - throw new NotImplementedException(); - - [Obsolete("Use VerifyTest.Recording.Stop(string identifier)", true)] - public static IReadOnlyList FinishRecording(string identifier) => - throw new NotImplementedException(); -} \ No newline at end of file diff --git a/src/Verify.EntityFramework/Verify.EntityFramework.csproj b/src/Verify.EntityFramework/Verify.EntityFramework.csproj index d37d08dc..124460e8 100644 --- a/src/Verify.EntityFramework/Verify.EntityFramework.csproj +++ b/src/Verify.EntityFramework/Verify.EntityFramework.csproj @@ -1,6 +1,6 @@ - net8.0 + net8.0;net9.0 diff --git a/src/Verify.EntityFrameworkClassic.Tests/Snippets/DataContext/SampleDbContext.cs b/src/Verify.EntityFrameworkClassic.Tests/Snippets/DataContext/SampleDbContext.cs index 7cbe9b0c..db2d0713 100644 --- a/src/Verify.EntityFrameworkClassic.Tests/Snippets/DataContext/SampleDbContext.cs +++ b/src/Verify.EntityFrameworkClassic.Tests/Snippets/DataContext/SampleDbContext.cs @@ -4,9 +4,9 @@ public DbSet Employees { get; set; } = null!; public DbSet Companies { get; set; } = null!; - protected override void OnModelCreating(DbModelBuilder modelBuilder) + protected override void OnModelCreating(DbModelBuilder model) { - modelBuilder.Entity(); - modelBuilder.Entity(); + model.Entity(); + model.Entity(); } } \ No newline at end of file diff --git a/src/Verify.EntityFrameworkClassic/Verify.EntityFrameworkClassic.csproj b/src/Verify.EntityFrameworkClassic/Verify.EntityFrameworkClassic.csproj index df98a277..d4e681f7 100644 --- a/src/Verify.EntityFrameworkClassic/Verify.EntityFrameworkClassic.csproj +++ b/src/Verify.EntityFrameworkClassic/Verify.EntityFrameworkClassic.csproj @@ -1,9 +1,8 @@ - net48;net6.0;net8.0 + net48;net8.0;net9.0 -