diff --git a/src/EntityFrameworkCore.Projections.Generator/ExpressionSyntaxRewriter.cs b/src/EntityFrameworkCore.Projections.Generator/ExpressionSyntaxRewriter.cs index be1b7e2..17c66f6 100644 --- a/src/EntityFrameworkCore.Projections.Generator/ExpressionSyntaxRewriter.cs +++ b/src/EntityFrameworkCore.Projections.Generator/ExpressionSyntaxRewriter.cs @@ -35,7 +35,7 @@ namespace EntityFrameworkCore.Projections.Generator if (nextNode is not null) { return SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, - SyntaxFactory.IdentifierName(ProjectionExpressionGenerator.ProjectionTargetParameterName), + SyntaxFactory.IdentifierName("@this"), nextNode ); } @@ -52,7 +52,7 @@ namespace EntityFrameworkCore.Projections.Generator if (symbolInfo.Symbol is not null && symbolInfo.Symbol.Kind is SymbolKind.Property or SymbolKind.Method or SymbolKind.Field && SymbolEqualityComparer.Default.Equals(symbolInfo.Symbol.ContainingType, _targetTypeSymbol)) { return SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, - SyntaxFactory.IdentifierName(ProjectionExpressionGenerator.ProjectionTargetParameterName), + SyntaxFactory.IdentifierName("@this"), node ); } diff --git a/src/EntityFrameworkCore.Projections.Generator/ParameterSyntaxRewriter.cs b/src/EntityFrameworkCore.Projections.Generator/ParameterSyntaxRewriter.cs index df77ae0..44ed0f4 100644 --- a/src/EntityFrameworkCore.Projections.Generator/ParameterSyntaxRewriter.cs +++ b/src/EntityFrameworkCore.Projections.Generator/ParameterSyntaxRewriter.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -14,28 +15,27 @@ namespace EntityFrameworkCore.Projections.Generator _semanticModel = semanticModel; } - public override SyntaxNode? VisitQualifiedName(QualifiedNameSyntax node) - { - // todo: Fully qualify these - return node; - } - - public override SyntaxNode? VisitParameter(ParameterSyntax node) + public override SyntaxNode? VisitIdentifierName(IdentifierNameSyntax node) { var symbol = _semanticModel.GetDeclaredSymbol(node); if (symbol is not null) { + node = SyntaxFactory.IdentifierName(symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)); } + return base.VisitIdentifierName(node); + } + + public override SyntaxNode? VisitParameter(ParameterSyntax node) + { var thisKeywordIndex = node.Modifiers.IndexOf(SyntaxKind.ThisKeyword); if (thisKeywordIndex != -1) { node = node.WithModifiers(node.Modifiers.RemoveAt(thisKeywordIndex)); } - - return node; + return base.VisitParameter(node); } } } diff --git a/src/EntityFrameworkCore.Projections.Generator/ProjectableDescriptor.cs b/src/EntityFrameworkCore.Projections.Generator/ProjectableDescriptor.cs index b8fadca..58aedf7 100644 --- a/src/EntityFrameworkCore.Projections.Generator/ProjectableDescriptor.cs +++ b/src/EntityFrameworkCore.Projections.Generator/ProjectableDescriptor.cs @@ -1,4 +1,5 @@ using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp.Syntax; using System; using System.Collections.Generic; using System.Linq; @@ -25,7 +26,7 @@ namespace EntityFrameworkCore.Projections.Generator public string ReturnTypeName { get; set; } - public string ParametersListString { get; set; } + public ParameterListSyntax ParametersList { get; set; } public SyntaxNode Body { get; set; } } diff --git a/src/EntityFrameworkCore.Projections.Generator/ProjectableInterpreter.cs b/src/EntityFrameworkCore.Projections.Generator/ProjectableInterpreter.cs index 052b9fc..4a34bb6 100644 --- a/src/EntityFrameworkCore.Projections.Generator/ProjectableInterpreter.cs +++ b/src/EntityFrameworkCore.Projections.Generator/ProjectableInterpreter.cs @@ -50,9 +50,26 @@ namespace EntityFrameworkCore.Projections.Generator ClassName = memberSymbol.ContainingType.Name, ClassNamespace = memberSymbol.ContainingType.ContainingNamespace.IsGlobalNamespace ? null : memberSymbol.ContainingType.ContainingNamespace.ToDisplayString(), MemberName = memberSymbol.Name, - NestedInClassNames = GetNestedInClassPath(memberSymbol.ContainingType) + NestedInClassNames = GetNestedInClassPath(memberSymbol.ContainingType), + ParametersList = SyntaxFactory.ParameterList() }; + if (!memberDeclarationSyntax.Modifiers.Any(SyntaxKind.StaticKeyword)) + { + descriptor.ParametersList = descriptor.ParametersList.AddParameters( + SyntaxFactory.Parameter( + SyntaxFactory.Identifier("@this") + ).WithType( + SyntaxFactory.ParseTypeName( + memberSymbol.ContainingType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) + ) + .WithTrailingTrivia( + SyntaxFactory.SyntaxTrivia(SyntaxKind.WhitespaceTrivia, " ") + ) + ) + ); + } + if (memberSymbol is IMethodSymbol methodSymbol && methodSymbol.IsExtensionMethod) { var targetTypeSymbol = methodSymbol.Parameters.First().Type; @@ -69,19 +86,23 @@ namespace EntityFrameworkCore.Projections.Generator { descriptor.ReturnTypeName = methodDeclarationSyntax.ReturnType.ToString(); descriptor.Body = expressionSyntaxRewriter.Visit(methodDeclarationSyntax.ExpressionBody.Expression); - descriptor.ParametersListString = parameterSyntaxRewriter.Visit(methodDeclarationSyntax.ParameterList).ToString(); + foreach (var additionalParameter in ((ParameterListSyntax)parameterSyntaxRewriter.Visit(methodDeclarationSyntax.ParameterList)).Parameters) + { + descriptor.ParametersList = descriptor.ParametersList.AddParameters(additionalParameter); + } } else if (memberDeclarationSyntax is PropertyDeclarationSyntax propertyDeclarationSyntax) { descriptor.ReturnTypeName = propertyDeclarationSyntax.Type.ToString(); descriptor.Body = expressionSyntaxRewriter.Visit(propertyDeclarationSyntax.ExpressionBody.Expression); - descriptor.ParametersListString = "()"; } else { return null; } + + descriptor.UsingDirectives = memberDeclarationSyntax.SyntaxTree .GetRoot() diff --git a/src/EntityFrameworkCore.Projections.Generator/ProjectionExpressionGenerator.cs b/src/EntityFrameworkCore.Projections.Generator/ProjectionExpressionGenerator.cs index c8e7e02..fab24cd 100644 --- a/src/EntityFrameworkCore.Projections.Generator/ProjectionExpressionGenerator.cs +++ b/src/EntityFrameworkCore.Projections.Generator/ProjectionExpressionGenerator.cs @@ -1,5 +1,6 @@ using EntityFrameworkCore.Projections.Services; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; using System; using System.Collections.Generic; @@ -12,8 +13,6 @@ namespace EntityFrameworkCore.Projections.Generator [Generator] public class ProjectionExpressionGenerator : ISourceGenerator { - public const string ProjectionTargetParameterName = "projectionTarget"; - public void Execute(GeneratorExecutionContext context) { if (context.SyntaxReceiver is not SyntaxReceiver receiver) @@ -49,6 +48,11 @@ namespace EntityFrameworkCore.Projections.Generator } var generatedClassName = ProjectionExpressionClassNameGenerator.GenerateName(projectable.ClassNamespace, projectable.NestedInClassNames, projectable.MemberName); + var lambdaTypeArguments = SyntaxFactory.TypeArgumentList( + SyntaxFactory.SeparatedList( + projectable.ParametersList.Parameters.Select(p => p.Type) + ) + ); resultBuilder.Append($@" namespace EntityFrameworkCore.Projections.Generated @@ -56,8 +60,8 @@ namespace EntityFrameworkCore.Projections.Generated {{ public static class {generatedClassName} {{ - public static System.Linq.Expressions.Expression> Expression{projectable.ParametersListString} => - {ProjectionTargetParameterName} => {projectable.Body}; + public static System.Linq.Expressions.Expression> Expression => + {projectable.ParametersList} => {projectable.Body}; }} }}"); diff --git a/src/EntityFrameworkCore.Projections/Services/ExpressionArgumentReplacer.cs b/src/EntityFrameworkCore.Projections/Services/ExpressionArgumentReplacer.cs index 62b4549..79b3a7d 100644 --- a/src/EntityFrameworkCore.Projections/Services/ExpressionArgumentReplacer.cs +++ b/src/EntityFrameworkCore.Projections/Services/ExpressionArgumentReplacer.cs @@ -9,23 +9,26 @@ namespace EntityFrameworkCore.Projections.Services { public class ExpressionArgumentReplacer : ExpressionVisitor { - readonly Expression _targetExpression; + readonly IEnumerable<(ParameterExpression parameter, Expression argument)>? _parameterArgumentMapping; - public ExpressionArgumentReplacer(Expression targetExpression) + public ExpressionArgumentReplacer(IEnumerable<(ParameterExpression, Expression)>? parameterArgumentMapping = null) { - _targetExpression = targetExpression; + _parameterArgumentMapping = parameterArgumentMapping; } protected override Expression VisitParameter(ParameterExpression node) { - if (node.Name == "projectionTarget") + var mappedArgument = _parameterArgumentMapping? + .Where(x => x.parameter == node) + .Select(x => x.argument) + .FirstOrDefault(); + + if (mappedArgument is not null) { - return _targetExpression; - } - else - { - return base.VisitParameter(node); + return mappedArgument; } + + return base.VisitParameter(node); } } } diff --git a/src/EntityFrameworkCore.Projections/Services/ProjectableExpressionReplacer.cs b/src/EntityFrameworkCore.Projections/Services/ProjectableExpressionReplacer.cs index bf23150..8efefab 100644 --- a/src/EntityFrameworkCore.Projections/Services/ProjectableExpressionReplacer.cs +++ b/src/EntityFrameworkCore.Projections/Services/ProjectableExpressionReplacer.cs @@ -15,24 +15,25 @@ namespace EntityFrameworkCore.Projections.Services { if (node.Method.GetCustomAttributes(true).OfType().Any()) { - var reflectedExpressionFactory = _resolver.FindGeneratedExpressionFactory(node.Method); - var reflectedExpresssion = reflectedExpressionFactory(node.Arguments); - if (reflectedExpresssion is not null) + var reflectedExpression = _resolver.FindGeneratedExpression(node.Method); + + var parameterArgumentMapping = node.Object is not null + ? Enumerable.Repeat((reflectedExpression.Parameters[0], node.Object), 1) + : Enumerable.Empty<(ParameterExpression, Expression)>(); + + if (reflectedExpression.Parameters.Count > 0) { - if (node.Object is not null) - { - var expressionArgumentReplacer = new ExpressionArgumentReplacer(node.Object); - return Visit( - expressionArgumentReplacer.Visit(reflectedExpresssion.Body) - ); - } - else - { - return Visit( - reflectedExpresssion.Body - ); - } + parameterArgumentMapping = parameterArgumentMapping.Concat( + node.Object is not null + ? reflectedExpression.Parameters.Skip(1).Zip(node.Arguments) + : reflectedExpression.Parameters.Zip(node.Arguments) + ); } + + var expressionArgumentReplacer = new ExpressionArgumentReplacer(parameterArgumentMapping); + return Visit( + expressionArgumentReplacer.Visit(reflectedExpression.Body) + ); } return base.VisitMethodCall(node); @@ -40,25 +41,24 @@ namespace EntityFrameworkCore.Projections.Services protected override Expression VisitMember(MemberExpression node) { - if (node.Member.GetCustomAttributes(true).OfType().Any()) + if (node.Member.GetCustomAttributes(false).OfType().Any()) { - var reflectedExpressionFactory = _resolver.FindGeneratedExpressionFactory(node.Member); - var reflectedExpression = reflectedExpressionFactory(null); - if (reflectedExpression is not null) + var reflectedExpression = _resolver.FindGeneratedExpression(node.Member); + + if (node.Expression is not null) { - if (node.Expression is not null) - { - var expressionArgumentReplacer = new ExpressionArgumentReplacer(node.Expression); - return Visit( - expressionArgumentReplacer.Visit(reflectedExpression.Body) - ); - } - else - { - return Visit( - reflectedExpression.Body - ); - } + var expressionArgumentReplacer = new ExpressionArgumentReplacer( + Enumerable.Repeat((reflectedExpression.Parameters[0], node.Expression), 1) + ); + return Visit( + expressionArgumentReplacer.Visit(reflectedExpression.Body) + ); + } + else + { + return Visit( + reflectedExpression.Body + ); } } diff --git a/src/EntityFrameworkCore.Projections/Services/ProjectionExpressionResolver.cs b/src/EntityFrameworkCore.Projections/Services/ProjectionExpressionResolver.cs index a98fc11..41011a9 100644 --- a/src/EntityFrameworkCore.Projections/Services/ProjectionExpressionResolver.cs +++ b/src/EntityFrameworkCore.Projections/Services/ProjectionExpressionResolver.cs @@ -12,9 +12,9 @@ namespace EntityFrameworkCore.Projections.Services { public sealed class ProjectionExpressionResolver { - readonly ConcurrentDictionary?, LambdaExpression>> _lookupCache = new(); + readonly ConcurrentDictionary _lookupCache = new(); - public Func?, LambdaExpression> FindGeneratedExpressionFactory(MemberInfo projectableMemberInfo) + public LambdaExpression FindGeneratedExpression(MemberInfo projectableMemberInfo) { var reflectedType = projectableMemberInfo.ReflectedType ?? throw new InvalidOperationException("Expected a valid type here"); var generatedContainingTypeName = ProjectionExpressionClassNameGenerator.GenerateFullName(reflectedType.Namespace, reflectedType.GetNestedTypePath().Select(x => x.Name), projectableMemberInfo.Name); @@ -35,32 +35,7 @@ namespace EntityFrameworkCore.Projections.Services }; } - return new Func?, LambdaExpression>(argumentExpressions => - { - if (argumentExpressions is null || argumentExpressions.Count is 0) - { - return expressionFactoryMethod.Invoke(null, null) as LambdaExpression ?? throw new InvalidOperationException("Expected lambda"); - } - else - { - var parameterExtractor = new ParameterExtractor(); - foreach (var argument in argumentExpressions) - { - parameterExtractor.Visit(argument); - } - - var lambda = Expression.Lambda>( - Expression.Call( - expressionFactoryMethod, - argumentExpressions - ), - parameterExtractor.ExtractedParameters - ); - - - return lambda.Compile().Invoke(); - } - }); + return expressionFactoryMethod.Invoke(null, null) as LambdaExpression ?? throw new InvalidOperationException("Expected lambda"); }); } } diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/ComplexModelTests.ProjectOverCollectionNavigationProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/ComplexModelTests.ProjectOverCollectionNavigationProperty.verified.txt new file mode 100644 index 0000000..d823c3d --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/ComplexModelTests.ProjectOverCollectionNavigationProperty.verified.txt @@ -0,0 +1,10 @@ +SELECT [t0].[RecordDate] +FROM [User] AS [u] +INNER JOIN ( + SELECT [t].[RecordDate], [t].[UserId] + FROM ( + SELECT [o].[RecordDate], [o].[UserId], ROW_NUMBER() OVER(PARTITION BY [o].[UserId] ORDER BY [o].[RecordDate] DESC) AS [row] + FROM [Order] AS [o] + ) AS [t] + WHERE [t].[row] <= 2 +) AS [t0] ON [u].[Id] = [t0].[UserId] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/ComplexModelTests.ProjectOverNavigationProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/ComplexModelTests.ProjectOverNavigationProperty.verified.txt new file mode 100644 index 0000000..f66db1a --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/ComplexModelTests.ProjectOverNavigationProperty.verified.txt @@ -0,0 +1,6 @@ +SELECT ( + SELECT TOP(1) [o].[RecordDate] + FROM [Order] AS [o] + WHERE [u].[Id] = [o].[UserId] + ORDER BY [o].[RecordDate] DESC) +FROM [User] AS [u] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/ComplexModelTests.cs b/tests/EntityFrameworkCore.Projections.FunctionalTests/ComplexModelTests.cs index 9afa7ff..71e0b3f 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/ComplexModelTests.cs +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/ComplexModelTests.cs @@ -8,14 +8,16 @@ using EntityFrameworkCore.Projections.FunctionalTests.Helpers; using EntityFrameworkCore.Projections.Services; using Microsoft.EntityFrameworkCore; using ScenarioTests; +using VerifyXunit; using Xunit; #nullable disable namespace EntityFrameworkCore.Projections.FunctionalTests { - - public partial class ComplexModelTests + + [UsesVerify] + public class ComplexModelTests { public class User { @@ -45,45 +47,27 @@ namespace EntityFrameworkCore.Projections.FunctionalTests public DateTime RecordDate { get; set; } } - [Scenario(NamingPolicy = ScenarioTestMethodNamingPolicy.Test)] - public void PlayScenario(ScenarioContext scenario) + [Fact] + public Task ProjectOverNavigationProperty() { using var dbContext = new SampleDbContext(); - scenario.Fact("We can project over a projectable navigation property", () => { - const string expectedQueryString = -@"SELECT ( - SELECT TOP(1) [o].[RecordDate] - FROM [Order] AS [o] - WHERE [u].[Id] = [o].[UserId] - ORDER BY [o].[RecordDate] DESC) -FROM [User] AS [u]"; + var query = dbContext.Set() + .Select(x => x.LastOrder.RecordDate); - var query = dbContext.Set() - .Select(x => x.LastOrder.RecordDate); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task ProjectOverCollectionNavigationProperty() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can project over a projectable navigation collection property", () => { - const string expectedQueryString = -@"SELECT [t0].[RecordDate] -FROM [User] AS [u] -INNER JOIN ( - SELECT [t].[RecordDate], [t].[UserId] - FROM ( - SELECT [o].[RecordDate], [o].[UserId], ROW_NUMBER() OVER(PARTITION BY [o].[UserId] ORDER BY [o].[RecordDate] DESC) AS [row] - FROM [Order] AS [o] - ) AS [t] - WHERE [t].[row] <= 2 -) AS [t0] ON [u].[Id] = [t0].[UserId]"; + var query = dbContext.Set() + .SelectMany(x => x.Last2Orders) + .Select(x => x.RecordDate); - var query = dbContext.Set() - .SelectMany(x => x.Last2Orders) - .Select(x => x.RecordDate); - - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + return Verifier.Verify(query.ToQueryString()); } } } diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/EntityFrameworkCore.Projections.FunctionalTests.csproj b/tests/EntityFrameworkCore.Projections.FunctionalTests/EntityFrameworkCore.Projections.FunctionalTests.csproj index 7d6f036..64481c3 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/EntityFrameworkCore.Projections.FunctionalTests.csproj +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/EntityFrameworkCore.Projections.FunctionalTests.csproj @@ -11,6 +11,7 @@ + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/Entity.cs b/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/Entity.cs index 82ff1b8..9a66c49 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/Entity.cs +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/Entity.cs @@ -1,11 +1,7 @@ namespace EntityFrameworkCore.Projections.FunctionalTests.ExtensionMethods { - - public partial class ExtensionMethodTests + public class Entity { - public class Entity - { - public int Id { get; set; } - } - } + public int Id { get; set; } + } } diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/EntityExtensions.cs b/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/EntityExtensions.cs index b501922..94957ce 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/EntityExtensions.cs +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/EntityExtensions.cs @@ -3,6 +3,9 @@ public static class EntityExtensions { [Projectable] - public static int Foo(this ExtensionMethodTests.Entity entity) => entity.Id + 1; + public static int Squared(this int i) => i * i; + + [Projectable] + public static int Foo(this Entity entity) => entity.Id + 1; } } diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/ExtensionMethodTests.ExtensionOnPrimitive.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/ExtensionMethodTests.ExtensionOnPrimitive.verified.txt new file mode 100644 index 0000000..4149c7b --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/ExtensionMethodTests.ExtensionOnPrimitive.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] * [e].[Id] +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/ExtensionMethodTests.SelectProjectableExtensionMethod.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/ExtensionMethodTests.SelectProjectableExtensionMethod.verified.txt new file mode 100644 index 0000000..ccd9b29 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/ExtensionMethodTests.SelectProjectableExtensionMethod.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] + 1 +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/ExtensionMethodTests.cs b/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/ExtensionMethodTests.cs index 5dc121f..1c0840a 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/ExtensionMethodTests.cs +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/ExtensionsMethods/ExtensionMethodTests.cs @@ -6,27 +6,35 @@ using System.Threading.Tasks; using EntityFrameworkCore.Projections.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore; using ScenarioTests; +using VerifyXunit; using Xunit; namespace EntityFrameworkCore.Projections.FunctionalTests.ExtensionMethods { - public partial class ExtensionMethodTests + [UsesVerify] + public class ExtensionMethodTests { - [Scenario(NamingPolicy = ScenarioTestMethodNamingPolicy.Test)] - public void PlayScenario(ScenarioContext scenario) + [Fact] + public Task ExtensionOnPrimitive() { using var dbContext = new SampleDbContext(); - scenario.Fact("We can select on a projectable extension method", () => { - const string expectedQueryString = "SELECT [e].[Id]\r\nFROM [Entity] AS [e]"; + var query = dbContext.Set() + .Select(x => x.Id.Squared()); - var query = dbContext.Set() - .Select(x => x.Foo()); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task SelectProjectableExtensionMethod() + { + using var dbContext = new SampleDbContext(); + var query = dbContext.Set() + .Select(x => x.Foo()); + + return Verifier.Verify(query.ToQueryString()); } } } diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.FilterOnProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.FilterOnProjectableProperty.verified.txt new file mode 100644 index 0000000..d326188 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.FilterOnProjectableProperty.verified.txt @@ -0,0 +1,3 @@ +SELECT [e].[Id] +FROM [Entity] AS [e] +WHERE ([e].[Id] + 1) = 2 \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.PassInReferenceArguments.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.PassInReferenceArguments.verified.txt new file mode 100644 index 0000000..738f7a4 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.PassInReferenceArguments.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] + [e].[Id] +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.PassInVariableArguments.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.PassInVariableArguments.verified.txt new file mode 100644 index 0000000..9a63c61 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.PassInVariableArguments.verified.txt @@ -0,0 +1,4 @@ +DECLARE @__argument_0 int = 1; + +SELECT [e].[Id] + @__argument_0 +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.SelectProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.SelectProjectableProperty.verified.txt new file mode 100644 index 0000000..ccd9b29 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.SelectProjectableProperty.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] + 1 +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.cs b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.cs index 7bdd0b8..925de42 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.cs +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullComplexFunctionTests.cs @@ -8,11 +8,13 @@ using EntityFrameworkCore.Projections.FunctionalTests.Helpers; using EntityFrameworkCore.Projections.Services; using Microsoft.EntityFrameworkCore; using ScenarioTests; +using VerifyXunit; using Xunit; namespace EntityFrameworkCore.Projections.FunctionalTests { - public partial class StatefullComplexFunctionTests + [UsesVerify] + public class StatefullComplexFunctionTests { public record Entity { @@ -22,53 +24,51 @@ namespace EntityFrameworkCore.Projections.FunctionalTests public int Computed(int argument) => Id + argument; } - [Scenario(NamingPolicy = ScenarioTestMethodNamingPolicy.Test)] - public void PlayScenario(ScenarioContext scenario) + + [Fact] + public Task FilterOnProjectableProperty() { - // Setup - using var dbContext = new SampleDbContext(); + using var dbContext = new SampleDbContext(); - scenario.Fact("We can filter on a projectable property", () => { - const string expectedQueryString = -@"DECLARE @__argument_0 int = 1; + var query = dbContext.Set() + .Where(x => x.Computed(1) == 2); -SELECT [e].[Id] -FROM [Entity] AS [e] -WHERE ([e].[Id] + @__argument_0) = 2"; + return Verifier.Verify(query.ToQueryString()); + } - var query = dbContext.Set().AsQueryable() - .Where(x => x.Computed(1) == 2); + [Fact] + public Task SelectProjectableProperty() + { + using var dbContext = new SampleDbContext(); - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + var query = dbContext.Set() + .Select(x => x.Computed(1)); - scenario.Fact("We can select on a projectable property", () => { - const string expectedQueryString = -@"DECLARE @__argument_0 int = 1; + return Verifier.Verify(query.ToQueryString()); + } -SELECT [e].[Id] + @__argument_0 -FROM [Entity] AS [e]"; - var query = dbContext.Set() - .AsQueryable() - .Select(x => x.Computed(1)); + [Fact] + public Task PassInVariableArguments() + { + using var dbContext = new SampleDbContext(); - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + var argument = 1; + var query = dbContext.Set() + .Select(x => x.Computed(argument)); - scenario.Fact("We can pass in variables", () => { - const string expectedQueryString = -@"DECLARE @__argument_0 int = 1; + return Verifier.Verify(query.ToQueryString()); + } -SELECT [e].[Id] + @__argument_0 -FROM [Entity] AS [e]"; + [Fact] + public Task PassInReferenceArguments() + { + using var dbContext = new SampleDbContext(); - var argument = 1; - var query = dbContext.Set() - .Select(x => x.Computed(argument)); + var query = dbContext.Set() + .Select(x => x.Computed(x.Id)); - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + return Verifier.Verify(query.ToQueryString()); } } } diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.CombineSelectProjectableProperties.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.CombineSelectProjectableProperties.verified.txt new file mode 100644 index 0000000..1a54cac --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.CombineSelectProjectableProperties.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] + ([e].[Id] * 2) +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.FilterOnComplexProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.FilterOnComplexProjectableProperty.verified.txt new file mode 100644 index 0000000..8541873 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.FilterOnComplexProjectableProperty.verified.txt @@ -0,0 +1,3 @@ +SELECT [e].[Id] +FROM [Entity] AS [e] +WHERE ([e].[Id] * 2) = 2 \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.FilterOnProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.FilterOnProjectableProperty.verified.txt new file mode 100644 index 0000000..c2ccd92 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.FilterOnProjectableProperty.verified.txt @@ -0,0 +1,3 @@ +SELECT [e].[Id] +FROM [Entity] AS [e] +WHERE [e].[Id] = 1 \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.SelectComplexProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.SelectComplexProjectableProperty.verified.txt new file mode 100644 index 0000000..028694e --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.SelectComplexProjectableProperty.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] * 2 +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.SelectProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.SelectProjectableProperty.verified.txt new file mode 100644 index 0000000..6a9e2b9 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.SelectProjectableProperty.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.cs b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.cs index ce3cad2..2f715ac 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.cs +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullPropertyTests.cs @@ -7,11 +7,13 @@ using System.Threading.Tasks; using EntityFrameworkCore.Projections.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore; using ScenarioTests; +using VerifyXunit; using Xunit; namespace EntityFrameworkCore.Projections.FunctionalTests { - public partial class StatefullPropertyTests + [UsesVerify] + public class StatefullPropertyTests { public record Entity { @@ -24,56 +26,59 @@ namespace EntityFrameworkCore.Projections.FunctionalTests public int Computed2 => Id * 2; } - [Scenario(NamingPolicy = ScenarioTestMethodNamingPolicy.Test)] - public void PlayScenario(ScenarioContext scenario) + [Fact] + public Task FilterOnProjectableProperty() { - // Setup - using var dbContext = new SampleDbContext(); + using var dbContext = new SampleDbContext(); - scenario.Fact("We can filter on a projectable property", () => { - const string expectedQueryString = "SELECT [e].[Id]\r\nFROM [Entity] AS [e]\r\nWHERE [e].[Id] = 1"; + var query = dbContext.Set() + .Where(x => x.Computed1 == 1); - var query = dbContext.Set() - .Where(x => x.Computed1 == 1); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task SelectProjectableProperty() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can select on a projectable property", () => { - const string expectedQueryString = "SELECT [e].[Id]\r\nFROM [Entity] AS [e]"; + var query = dbContext.Set() + .Select(x => x.Computed1); - var query = dbContext.Set() - .Select(x => x.Computed1); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task FilterOnComplexProjectableProperty() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can filter on a more complex projectable property", () => { - const string expectedQueryString = "SELECT [e].[Id]\r\nFROM [Entity] AS [e]\r\nWHERE ([e].[Id] * 2) = 2"; + var query = dbContext.Set() + .Where(x => x.Computed2 == 2); - var query = dbContext.Set() - .Where(x => x.Computed2 == 2); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task SelectComplexProjectableProperty() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can select a more complex projectable property", () => { - const string expectedQueryString = "SELECT [e].[Id] * 2\r\nFROM [Entity] AS [e]"; + var query = dbContext.Set() + .Select(x => x.Computed2); - var query = dbContext.Set() - .Select(x => x.Computed2); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task CombineSelectProjectableProperties() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can combine multiple projectable properties", () => { - const string expectedQueryString = "SELECT [e].[Id] + ([e].[Id] * 2)\r\nFROM [Entity] AS [e]"; + var query = dbContext.Set() + .Select(x => x.Computed1 + x.Computed2); - var query = dbContext.Set() - .Select(x => x.Computed1 + x.Computed2); - - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + return Verifier.Verify(query.ToQueryString()); } } } diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.CombineSelectProjectableProperties.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.CombineSelectProjectableProperties.verified.txt new file mode 100644 index 0000000..1a54cac --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.CombineSelectProjectableProperties.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] + ([e].[Id] * 2) +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.FilterOnComplexProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.FilterOnComplexProjectableProperty.verified.txt new file mode 100644 index 0000000..8541873 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.FilterOnComplexProjectableProperty.verified.txt @@ -0,0 +1,3 @@ +SELECT [e].[Id] +FROM [Entity] AS [e] +WHERE ([e].[Id] * 2) = 2 \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.FilterOnProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.FilterOnProjectableProperty.verified.txt new file mode 100644 index 0000000..c2ccd92 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.FilterOnProjectableProperty.verified.txt @@ -0,0 +1,3 @@ +SELECT [e].[Id] +FROM [Entity] AS [e] +WHERE [e].[Id] = 1 \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.SelectComplexProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.SelectComplexProjectableProperty.verified.txt new file mode 100644 index 0000000..028694e --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.SelectComplexProjectableProperty.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] * 2 +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.SelectProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.SelectProjectableProperty.verified.txt new file mode 100644 index 0000000..6a9e2b9 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.SelectProjectableProperty.verified.txt @@ -0,0 +1,2 @@ +SELECT [e].[Id] +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.cs b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.cs index cea1175..a561532 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.cs +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatefullSimpleFunctionTests.cs @@ -7,11 +7,13 @@ using System.Threading.Tasks; using EntityFrameworkCore.Projections.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore; using ScenarioTests; +using VerifyXunit; using Xunit; namespace EntityFrameworkCore.Projections.FunctionalTests { - public partial class StatefullSimpleFunctionTests + [UsesVerify] + public class StatefullSimpleFunctionTests { public record Entity { @@ -26,56 +28,59 @@ namespace EntityFrameworkCore.Projections.FunctionalTests public int Test(int i) => i; } - [Scenario(NamingPolicy = ScenarioTestMethodNamingPolicy.Test)] - public void PlayScenario(ScenarioContext scenario) + [Fact] + public Task FilterOnProjectableProperty() { - // Setup using var dbContext = new SampleDbContext(); - scenario.Fact("We can filter on a projectable property", () => { - const string expectedQueryString = "SELECT [e].[Id]\r\nFROM [Entity] AS [e]\r\nWHERE [e].[Id] = 1"; + var query = dbContext.Set() + .Where(x => x.Computed1() == 1); - var query = dbContext.Set() - .Where(x => x.Computed1() == 1); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task SelectProjectableProperty() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can select on a projectable property", () => { - const string expectedQueryString = "SELECT [e].[Id]\r\nFROM [Entity] AS [e]"; + var query = dbContext.Set() + .Select(x => x.Computed1()); - var query = dbContext.Set() - .Select(x => x.Computed1()); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task FilterOnComplexProjectableProperty() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can filter on a more complex projectable property", () => { - const string expectedQueryString = "SELECT [e].[Id]\r\nFROM [Entity] AS [e]\r\nWHERE ([e].[Id] * 2) = 2"; + var query = dbContext.Set() + .Where(x => x.Computed2() == 2); - var query = dbContext.Set() - .Where(x => x.Computed2() == 2); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task SelectComplexProjectableProperty() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can select a more complex projectable property", () => { - const string expectedQueryString = "SELECT [e].[Id] * 2\r\nFROM [Entity] AS [e]"; + var query = dbContext.Set() + .Select(x => x.Computed2()); - var query = dbContext.Set() - .Select(x => x.Computed2()); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task CombineSelectProjectableProperties() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can combine multiple projectable properties", () => { - const string expectedQueryString = "SELECT [e].[Id] + ([e].[Id] * 2)\r\nFROM [Entity] AS [e]"; + var query = dbContext.Set() + .Select(x => x.Computed1() + x.Computed2()); - var query = dbContext.Set() - .Select(x => x.Computed1() + x.Computed2()); - - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + return Verifier.Verify(query.ToQueryString()); } } } diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.FilterOnProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.FilterOnProjectableProperty.verified.txt new file mode 100644 index 0000000..7244f2c --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.FilterOnProjectableProperty.verified.txt @@ -0,0 +1,3 @@ +SELECT [e].[Id] +FROM [Entity] AS [e] +WHERE 0 = 1 \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.PassInVariableArguments.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.PassInVariableArguments.verified.txt new file mode 100644 index 0000000..797c051 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.PassInVariableArguments.verified.txt @@ -0,0 +1,4 @@ +DECLARE @__argument_0 int = 1; + +SELECT @__argument_0 +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.SelectProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.SelectProjectableProperty.verified.txt new file mode 100644 index 0000000..7ff8a35 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.SelectProjectableProperty.verified.txt @@ -0,0 +1,2 @@ +SELECT 0 +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.cs b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.cs index 1246f78..ddbc59e 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.cs +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessComplexFunctionTests.cs @@ -8,11 +8,13 @@ using EntityFrameworkCore.Projections.FunctionalTests.Helpers; using EntityFrameworkCore.Projections.Services; using Microsoft.EntityFrameworkCore; using ScenarioTests; +using VerifyXunit; using Xunit; namespace EntityFrameworkCore.Projections.FunctionalTests { - public partial class StatelessComplexFunctionTests + [UsesVerify] + public class StatelessComplexFunctionTests { public record Entity { @@ -22,53 +24,39 @@ namespace EntityFrameworkCore.Projections.FunctionalTests public int Computed(int argument1) => argument1; } - [Scenario(NamingPolicy = ScenarioTestMethodNamingPolicy.Test)] - public void PlayScenario(ScenarioContext scenario) + + [Fact] + public Task FilterOnProjectableProperty() { - // Setup - using var dbContext = new SampleDbContext(); + using var dbContext = new SampleDbContext(); - scenario.Fact("We can filter on a projectable property", () => { - const string expectedQueryString = -@"DECLARE @__p_0 bit = CAST(0 AS bit); + var query = dbContext.Set().AsQueryable() + .Where(x => x.Computed(0) == 1); -SELECT [e].[Id] -FROM [Entity] AS [e] -WHERE @__p_0 = CAST(1 AS bit)"; + return Verifier.Verify(query.ToQueryString()); + } - var query = dbContext.Set().AsQueryable() - .Where(x => x.Computed(0) == 1); + [Fact] + public Task SelectProjectableProperty() + { + using var dbContext = new SampleDbContext(); - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + var query = dbContext.Set() + .Select(x => x.Computed(0)); - scenario.Fact("We can select on a projectable property", () => { - const string expectedQueryString = -@"DECLARE @__argument1_0 int = 0; + return Verifier.Verify(query.ToQueryString()); + } -SELECT @__argument1_0 -FROM [Entity] AS [e]"; + [Fact] + public Task PassInVariableArguments() + { + using var dbContext = new SampleDbContext(); - var query = dbContext.Set() - .AsQueryable() - .Select(x => x.Computed(0)); + var argument = 1; + var query = dbContext.Set() + .Select(x => x.Computed(argument)); - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); - - scenario.Fact("We can pass in variables", () => { - const string expectedQueryString = -@"DECLARE @__argument1_0 int = 0; - -SELECT @__argument1_0 -FROM [Entity] AS [e]"; - - var argument = 0; - var query = dbContext.Set() - .Select(x => x.Computed(argument)); - - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + return Verifier.Verify(query.ToQueryString()); } } } diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessPropertyTests.FilterOnProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessPropertyTests.FilterOnProjectableProperty.verified.txt new file mode 100644 index 0000000..7244f2c --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessPropertyTests.FilterOnProjectableProperty.verified.txt @@ -0,0 +1,3 @@ +SELECT [e].[Id] +FROM [Entity] AS [e] +WHERE 0 = 1 \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessPropertyTests.SelectProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessPropertyTests.SelectProjectableProperty.verified.txt new file mode 100644 index 0000000..7ff8a35 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessPropertyTests.SelectProjectableProperty.verified.txt @@ -0,0 +1,2 @@ +SELECT 0 +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessPropertyTests.cs b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessPropertyTests.cs index dc2d59a..51dd9a4 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessPropertyTests.cs +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessPropertyTests.cs @@ -7,11 +7,13 @@ using System.Threading.Tasks; using EntityFrameworkCore.Projections.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore; using ScenarioTests; +using VerifyXunit; using Xunit; namespace EntityFrameworkCore.Projections.FunctionalTests { - public partial class StatelessPropertyTests + [UsesVerify] + public class StatelessPropertyTests { public record Entity { @@ -21,29 +23,26 @@ namespace EntityFrameworkCore.Projections.FunctionalTests public int Computed => 0; } - [Scenario(NamingPolicy = ScenarioTestMethodNamingPolicy.Test)] - public void PlayScenario(ScenarioContext scenario) + [Fact] + public Task FilterOnProjectableProperty() { - // Setup - using var dbContext = new SampleDbContext(); + using var dbContext = new SampleDbContext(); - scenario.Fact("We can filter on a projectable property", () => { - const string expectedQueryString = "SELECT [e].[Id]\r\nFROM [Entity] AS [e]\r\nWHERE 0 = 1"; + var query = dbContext.Set().AsQueryable() + .Where(x => x.Computed == 1); - var query = dbContext.Set() - .Where(x => x.Computed == 1); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task SelectProjectableProperty() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can select on a projectable property", () => { - const string expectedQueryString = "SELECT 0\r\nFROM [Entity] AS [e]"; + var query = dbContext.Set() + .Select(x => x.Computed); - var query = dbContext.Set() - .Select(x => x.Computed); - - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + return Verifier.Verify(query.ToQueryString()); } } } diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessSimpleFunctionTests.FilterOnProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessSimpleFunctionTests.FilterOnProjectableProperty.verified.txt new file mode 100644 index 0000000..7244f2c --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessSimpleFunctionTests.FilterOnProjectableProperty.verified.txt @@ -0,0 +1,3 @@ +SELECT [e].[Id] +FROM [Entity] AS [e] +WHERE 0 = 1 \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessSimpleFunctionTests.SelectProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessSimpleFunctionTests.SelectProjectableProperty.verified.txt new file mode 100644 index 0000000..7ff8a35 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessSimpleFunctionTests.SelectProjectableProperty.verified.txt @@ -0,0 +1,2 @@ +SELECT 0 +FROM [Entity] AS [e] \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessSimpleFunctionTests.cs b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessSimpleFunctionTests.cs index 7f19500..6459e22 100644 --- a/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessSimpleFunctionTests.cs +++ b/tests/EntityFrameworkCore.Projections.FunctionalTests/StatelessSimpleFunctionTests.cs @@ -7,11 +7,13 @@ using System.Threading.Tasks; using EntityFrameworkCore.Projections.FunctionalTests.Helpers; using Microsoft.EntityFrameworkCore; using ScenarioTests; +using VerifyXunit; using Xunit; namespace EntityFrameworkCore.Projections.FunctionalTests { - public partial class StatelessSimpleFunctionTests + [UsesVerify] + public class StatelessSimpleFunctionTests { public record Entity { @@ -21,29 +23,26 @@ namespace EntityFrameworkCore.Projections.FunctionalTests public int Computed() => 0; } - [Scenario(NamingPolicy = ScenarioTestMethodNamingPolicy.Test)] - public void PlayScenario(ScenarioContext scenario) + [Fact] + public Task FilterOnProjectableProperty() { - // Setup - using var dbContext = new SampleDbContext(); + using var dbContext = new SampleDbContext(); - scenario.Fact("We can filter on a projectable property", () => { - const string expectedQueryString = "SELECT [e].[Id]\r\nFROM [Entity] AS [e]\r\nWHERE 0 = 1"; + var query = dbContext.Set().AsQueryable() + .Where(x => x.Computed() == 1); - var query = dbContext.Set() - .Where(x => x.Computed() == 1); + return Verifier.Verify(query.ToQueryString()); + } - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + [Fact] + public Task SelectProjectableProperty() + { + using var dbContext = new SampleDbContext(); - scenario.Fact("We can select on a projectable property", () => { - const string expectedQueryString = "SELECT 0\r\nFROM [Entity] AS [e]"; + var query = dbContext.Set() + .Select(x => x.Computed()); - var query = dbContext.Set() - .Select(x => x.Computed()); - - Assert.Equal(expectedQueryString, query.ToQueryString()); - }); + return Verifier.Verify(query.ToQueryString()); } } } diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ArgumentlessProjectableComputedMethod.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ArgumentlessProjectableComputedMethod.verified.txt index 33389b9..9d7279c 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ArgumentlessProjectableComputedMethod.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ArgumentlessProjectableComputedMethod.verified.txt @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression() => - projectionTarget => 0; + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this) => 0; } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.MoreComplexProjectableComputedProperty.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.MoreComplexProjectableComputedProperty.verified.txt index cc2cc9d..a574c18 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.MoreComplexProjectableComputedProperty.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.MoreComplexProjectableComputedProperty.verified.txt @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression() => - projectionTarget => projectionTarget.Bar + projectionTarget.Bar + projectionTarget.Bar; + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this) => @this.Bar + @this.Bar + @this.Bar; } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithMultipleArguments.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithMultipleArguments.verified.txt index ac95dc4..3807263 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithMultipleArguments.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithMultipleArguments.verified.txt @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression(int a, string b, object d) => - projectionTarget => a; + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this,int a,string b,object d) => a; } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithSingleArgument.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithSingleArgument.verified.txt index c02a066..6efe3ba 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithSingleArgument.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedMethodWithSingleArgument.verified.txt @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression(int i) => - projectionTarget => i; + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this,int i) => i; } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedPropertyMethod.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedPropertyMethod.verified.txt index ea2738f..0745df1 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedPropertyMethod.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedPropertyMethod.verified.txt @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression() => - projectionTarget => projectionTarget.Bar(); + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this) => @this.Bar(); } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedPropertyUsingThis.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedPropertyUsingThis.verified.txt index 16acc1e..8f58a82 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedPropertyUsingThis.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableComputedPropertyUsingThis.verified.txt @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression() => - projectionTarget => projectionTarget.Bar; + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this) => @this.Bar; } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod.verified.txt index 9cd289f..8f7bc6c 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod.verified.txt @@ -8,7 +8,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression(D d) => - projectionTarget => 1; + public static System.Linq.Expressions.Expression> Expression => + (D d) => 1; } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod2.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod2.verified.txt new file mode 100644 index 0000000..10f8646 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectableExtensionMethod2.verified.txt @@ -0,0 +1,15 @@ +using System; +using System.Linq; +using EntityFrameworkCore.Projections; +using System; +using Foo; + +namespace EntityFrameworkCore.Projections.Generated +#nullable disable +{ + public static class Foo_C_Foo + { + public static System.Linq.Expressions.Expression> Expression => + (int i) => i; + } +} \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectablePropertyToNavigationalProperty.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectablePropertyToNavigationalProperty.verified.txt index 9523e9c..6b6271e 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectablePropertyToNavigationalProperty.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.ProjectablePropertyToNavigationalProperty.verified.txt @@ -8,7 +8,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression() => - projectionTarget => projectionTarget.Dees.First(); + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this) => @this.Dees.First(); } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableComputedInNestedClassProperty.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableComputedInNestedClassProperty.verified.txt index 2b4f62d..7dcbc1a 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableComputedInNestedClassProperty.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableComputedInNestedClassProperty.verified.txt @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_D_Foo { - public static System.Linq.Expressions.Expression> Expression() => - projectionTarget => projectionTarget.Bar + 1; + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C.D @this) => @this.Bar + 1; } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableComputedProperty.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableComputedProperty.verified.txt index 9abcef9..6a3be3d 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableComputedProperty.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableComputedProperty.verified.txt @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression() => - projectionTarget => projectionTarget.Bar + 1; + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this) => @this.Bar + 1; } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableMethod.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableMethod.verified.txt index f29473a..7fbd574 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableMethod.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableMethod.verified.txt @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression() => - projectionTarget => 1; + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this) => 1; } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableProperty.verified.txt b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableProperty.verified.txt index f29473a..7fbd574 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableProperty.verified.txt +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.SimpleProjectableProperty.verified.txt @@ -7,7 +7,7 @@ namespace EntityFrameworkCore.Projections.Generated { public static class Foo_C_Foo { - public static System.Linq.Expressions.Expression> Expression() => - projectionTarget => 1; + public static System.Linq.Expressions.Expression> Expression => + (global::Foo.C @this) => 1; } } \ No newline at end of file diff --git a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.cs b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.cs index b95ba11..cc746fe 100644 --- a/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.cs +++ b/tests/EntityFrameworkCore.Projections.Generator.Tests/ProjectionExpressionGeneratorTests.cs @@ -317,6 +317,29 @@ namespace Foo { return Verifier.Verify(result.GeneratedTrees[0].ToString()); } + [Fact] + public Task ProjectableExtensionMethod2() + { + var compilation = CreateCompilation(@" +using System; +using System.Linq; +using EntityFrameworkCore.Projections; +namespace Foo { + static class C { + [Projectable] + public static int Foo(this int i) => i; + } +} +"); + + var result = RunGenerator(compilation); + + Assert.Empty(result.Diagnostics); + Assert.Single(result.GeneratedTrees); + + return Verifier.Verify(result.GeneratedTrees[0].ToString()); + } + #region Helpers diff --git a/tests/EntityFrameworkCore.Projections.Tests/Services/ProjectableExpressionReplacerTests.cs b/tests/EntityFrameworkCore.Projections.Tests/Services/ProjectableExpressionReplacerTests.cs new file mode 100644 index 0000000..7cac009 --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.Tests/Services/ProjectableExpressionReplacerTests.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; + +namespace EntityFrameworkCore.Projections.Tests.Services +{ + public class ProjectableExpressionReplacerTests + { + } +} diff --git a/tests/EntityFrameworkCore.Projections.Tests/Services/ProjectionExpressionResolverTests.cs b/tests/EntityFrameworkCore.Projections.Tests/Services/ProjectionExpressionResolverTests.cs new file mode 100644 index 0000000..00747ba --- /dev/null +++ b/tests/EntityFrameworkCore.Projections.Tests/Services/ProjectionExpressionResolverTests.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; +using System.Text; +using System.Threading.Tasks; +using Xunit; + +namespace EntityFrameworkCore.Projections.Tests.Services +{ + public class ProjectionExpressionResolverTests + { + //public Expression> Test1(int arg1) + // => arg1 + 1; + + [Fact] + public void Foo1() + { + + + } + } +}