Skip to content
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
2 changes: 1 addition & 1 deletion src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project>
<PropertyGroup>
<NoWarn>CS1591;CS0649;CS8632;EF1001</NoWarn>
<Version>12.4.0</Version>
<Version>13.0.0</Version>
<LangVersion>preview</LangVersion>
<AssemblyVersion>1.0.0</AssemblyVersion>
<PackageTags>EntityFramework, Verify</PackageTags>
Expand Down
20 changes: 10 additions & 10 deletions src/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,25 @@
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="EfClassicLocalDb" Version="19.2.1" />
<PackageVersion Include="EfLocalDb" Version="19.2.1" />
<PackageVersion Include="EfClassicLocalDb" Version="20.0.0" />
<PackageVersion Include="EfLocalDb" Version="20.0.0" />
<PackageVersion Include="EntityFramework" Version="6.5.1" />
<PackageVersion Include="MarkdownSnippets.MsBuild" Version="27.0.2" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="8.0.11" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.11" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="8.0.11" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.11" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.11" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.11" />
<PackageVersion Include="Microsoft.AspNetCore.Mvc.Testing" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.InMemory" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Relational" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="9.0.0" />
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.0" />
<PackageVersion Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageVersion Include="NUnit" Version="4.2.2" />
<PackageVersion Include="NUnit3TestAdapter" Version="4.6.0" />
<PackageVersion Include="Polyfill" Version="7.5.0" />
<PackageVersion Include="ProjectDefaults" Version="1.0.144" />
<PackageVersion Include="System.Data.SqlClient" Version="4.9.0" />
<PackageVersion Include="Verify" Version="28.2.1" />
<PackageVersion Include="Verify" Version="28.3.2" />
<PackageVersion Include="Verify.DiffPlex" Version="3.1.2" />
<PackageVersion Include="Verify.NUnit" Version="28.2.1" />
<PackageVersion Include="Verify.NUnit" Version="28.3.2" />
<PackageVersion Include="Verify.SqlServer" Version="10.1.0" />
</ItemGroup>
</Project>
3 changes: 1 addition & 2 deletions src/Verify.EntityFramework.Tests/GlobalUsings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
global using Microsoft.Extensions.Hosting;
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
public DbSet<Employee> Employees { get; set; } = null!;
public DbSet<Company> Companies { get; set; } = null!;

protected override void OnModelCreating(ModelBuilder builder)
protected override void OnModelCreating(ModelBuilder model)
{
builder
model
.Entity<Company>()
.HasMany(_ => _.Employees)
.WithOne(_ => _.Company)
.IsRequired();
builder.Entity<Employee>();
model.Entity<Employee>();
}
}
15 changes: 15 additions & 0 deletions src/Verify.EntityFramework/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,21 @@ public static IQueryable<object> AsNoTracking(this IQueryable<object> set, Type
return (IQueryable<object>) 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<object> Set(this DbContext data, Type t) =>
(IQueryable<object>) setMethod
.MakeGenericMethod(t)
Expand Down
3 changes: 2 additions & 1 deletion src/Verify.EntityFramework/LogCommandInterceptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ public override ValueTask<int> 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;
}
Expand Down
80 changes: 55 additions & 25 deletions src/Verify.EntityFramework/MissingOrder/MissingOrderByVisitor.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
sealed class MissingOrderByVisitor : ExpressionVisitor
sealed class MissingOrderByVisitor :
ExpressionVisitor
{
List<OrderingExpression> orderedExpressions = [];
List<TableExpressionBase> orderedTables = [];

public override Expression? Visit(Expression? expression)
{
Expand All @@ -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);
}
}
}
Expand All @@ -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);
Expand All @@ -86,6 +94,28 @@ SelectExpression must have at least one ordering.
}
}

static bool TryFindTable(IReadOnlyList<TableExpressionBase> 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);
}
12 changes: 5 additions & 7 deletions src/Verify.EntityFramework/MissingOrder/RelationalFactory.cs
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
14 changes: 6 additions & 8 deletions src/Verify.EntityFramework/MissingOrder/RelationalVisitor.cs
Original file line number Diff line number Diff line change
@@ -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);
Expand Down
23 changes: 0 additions & 23 deletions src/Verify.EntityFramework/SqlRecording.cs

This file was deleted.

2 changes: 1 addition & 1 deletion src/Verify.EntityFramework/Verify.EntityFramework.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFrameworks>net8.0;net9.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
public DbSet<Employee> Employees { get; set; } = null!;
public DbSet<Company> Companies { get; set; } = null!;

protected override void OnModelCreating(DbModelBuilder modelBuilder)
protected override void OnModelCreating(DbModelBuilder model)
{
modelBuilder.Entity<Company>();
modelBuilder.Entity<Employee>();
model.Entity<Company>();
model.Entity<Employee>();
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net48;net6.0;net8.0</TargetFrameworks>
<TargetFrameworks>net48;net8.0;net9.0</TargetFrameworks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Polyfill" PrivateAssets="all" />
<PackageReference Include="EntityFramework" />
<PackageReference Include="Verify" />
<PackageReference Include="ProjectDefaults" PrivateAssets="all" />
Expand Down
Loading