mirror of
https://github.com/zoriya/EntityFrameworkCore.Projectables.git
synced 2026-05-28 12:43:17 +00:00
Fully qualify Type names where possible
This commit is contained in:
@@ -45,5 +45,31 @@ namespace EntityFrameworkCore.Projectables.Generator
|
|||||||
|
|
||||||
return base.VisitNullableType(node);
|
return base.VisitNullableType(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override SyntaxNode? VisitIdentifierName(IdentifierNameSyntax node)
|
||||||
|
{
|
||||||
|
var typeInfo = _semanticModel.GetTypeInfo(node);
|
||||||
|
if (typeInfo.Type is not null)
|
||||||
|
{
|
||||||
|
return SyntaxFactory.ParseTypeName(
|
||||||
|
typeInfo.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)
|
||||||
|
).WithTriviaFrom(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.VisitIdentifierName(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override SyntaxNode? VisitQualifiedName(QualifiedNameSyntax node)
|
||||||
|
{
|
||||||
|
var typeInfo = _semanticModel.GetTypeInfo(node);
|
||||||
|
if (typeInfo.Type is not null)
|
||||||
|
{
|
||||||
|
return SyntaxFactory.ParseTypeName(
|
||||||
|
typeInfo.Type.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)
|
||||||
|
).WithTriviaFrom(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.VisitQualifiedName(node);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,6 +130,15 @@ namespace EntityFrameworkCore.Projectables.Generator
|
|||||||
}
|
}
|
||||||
else if (symbolInfo.Symbol.Kind is SymbolKind.Property or SymbolKind.Method or SymbolKind.Field && SymbolEqualityComparer.Default.Equals(symbolInfo.Symbol.ContainingType, _targetTypeSymbol))
|
else if (symbolInfo.Symbol.Kind is SymbolKind.Property or SymbolKind.Method or SymbolKind.Field && SymbolEqualityComparer.Default.Equals(symbolInfo.Symbol.ContainingType, _targetTypeSymbol))
|
||||||
{
|
{
|
||||||
|
if (node.Parent is MemberAccessExpressionSyntax parentMemberAccessNode)
|
||||||
|
{
|
||||||
|
var targetSymbolInfo = _semanticModel.GetSymbolInfo(parentMemberAccessNode.Expression);
|
||||||
|
if (targetSymbolInfo.Symbol is { Kind: SymbolKind.Parameter })
|
||||||
|
{
|
||||||
|
return base.VisitIdentifierName(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
|
return SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
|
||||||
SyntaxFactory.IdentifierName("@this"),
|
SyntaxFactory.IdentifierName("@this"),
|
||||||
node
|
node
|
||||||
|
|||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
SELECT [t0].[Id], [t0].[EntityId], [t0].[ParentId]
|
||||||
|
FROM [Entity] AS [e]
|
||||||
|
LEFT JOIN (
|
||||||
|
SELECT [t].[Id], [t].[EntityId], [t].[ParentId]
|
||||||
|
FROM (
|
||||||
|
SELECT [e0].[Id], [e0].[EntityId], [e0].[ParentId], ROW_NUMBER() OVER(PARTITION BY [e0].[EntityId] ORDER BY [e0].[Id]) AS [row]
|
||||||
|
FROM [Entity] AS [e0]
|
||||||
|
) AS [t]
|
||||||
|
WHERE [t].[row] <= 1
|
||||||
|
) AS [t0] ON [e].[Id] = [t0].[EntityId]
|
||||||
+9
-17
@@ -1,37 +1,29 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data.SqlTypes;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using EntityFrameworkCore.Projectables.FunctionalTests.Helpers;
|
using EntityFrameworkCore.Projectables.FunctionalTests.Helpers;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using ScenarioTests;
|
|
||||||
using VerifyXunit;
|
using VerifyXunit;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
||||||
namespace EntityFrameworkCore.Projectables.FunctionalTests
|
namespace EntityFrameworkCore.Projectables.FunctionalTests
|
||||||
{
|
{
|
||||||
[UsesVerify]
|
[UsesVerify]
|
||||||
public class StatelessPropertyTests
|
public class TypeNameQualificationTests
|
||||||
{
|
{
|
||||||
public record Entity
|
public record Entity
|
||||||
{
|
{
|
||||||
public int Id { get; set; }
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
public int? ParentId { get; set; }
|
||||||
|
|
||||||
|
public ICollection<Entity> Children { get; } = new List<Entity>();
|
||||||
|
|
||||||
[Projectable]
|
[Projectable]
|
||||||
public int Computed => 0;
|
public Entity? FirstChild =>
|
||||||
}
|
Children.OrderBy(x => x.Id).FirstOrDefault();
|
||||||
|
|
||||||
[Fact]
|
|
||||||
public Task FilterOnProjectableProperty()
|
|
||||||
{
|
|
||||||
using var dbContext = new SampleDbContext<Entity>();
|
|
||||||
|
|
||||||
var query = dbContext.Set<Entity>().AsQueryable()
|
|
||||||
.Where(x => x.Computed == 1);
|
|
||||||
|
|
||||||
return Verifier.Verify(query.ToQueryString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
@@ -40,7 +32,7 @@ namespace EntityFrameworkCore.Projectables.FunctionalTests
|
|||||||
using var dbContext = new SampleDbContext<Entity>();
|
using var dbContext = new SampleDbContext<Entity>();
|
||||||
|
|
||||||
var query = dbContext.Set<Entity>()
|
var query = dbContext.Set<Entity>()
|
||||||
.Select(x => x.Computed);
|
.Select(x => x.FirstChild);
|
||||||
|
|
||||||
return Verifier.Verify(query.ToQueryString());
|
return Verifier.Verify(query.ToQueryString());
|
||||||
}
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using EntityFrameworkCore.Projectables;
|
||||||
|
using Foo;
|
||||||
|
|
||||||
|
namespace EntityFrameworkCore.Projectables.Generated
|
||||||
|
#nullable disable
|
||||||
|
{
|
||||||
|
public static class Foo_EntityExtensions_Entity_Something
|
||||||
|
{
|
||||||
|
public static System.Linq.Expressions.Expression<System.Func<global::Foo.EntityExtensions.Entity, global::Foo.EntityExtensions.Entity>> Expression()
|
||||||
|
{
|
||||||
|
return (global::Foo.EntityExtensions.Entity entity) =>
|
||||||
|
entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -9,9 +9,9 @@ namespace EntityFrameworkCore.Projectables.Generated
|
|||||||
{
|
{
|
||||||
public static class Foo_EntityExtensions_GetFirstRelatedIgnoreNulls
|
public static class Foo_EntityExtensions_GetFirstRelatedIgnoreNulls
|
||||||
{
|
{
|
||||||
public static System.Linq.Expressions.Expression<System.Func<Entity, Entity>> Expression()
|
public static System.Linq.Expressions.Expression<System.Func<global::Foo.EntityExtensions.Entity, global::Foo.EntityExtensions.Entity>> Expression()
|
||||||
{
|
{
|
||||||
return (Entity entity) =>
|
return (global::Foo.EntityExtensions.Entity entity) =>
|
||||||
entity.RelatedEntities[0];
|
entity.RelatedEntities[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -9,9 +9,9 @@ namespace EntityFrameworkCore.Projectables.Generated
|
|||||||
{
|
{
|
||||||
public static class Foo_EntityExtensions_GetFirstRelatedIgnoreNulls
|
public static class Foo_EntityExtensions_GetFirstRelatedIgnoreNulls
|
||||||
{
|
{
|
||||||
public static System.Linq.Expressions.Expression<System.Func<Entity, Entity>> Expression()
|
public static System.Linq.Expressions.Expression<System.Func<global::Foo.EntityExtensions.Entity, global::Foo.EntityExtensions.Entity>> Expression()
|
||||||
{
|
{
|
||||||
return (Entity entity) =>
|
return (global::Foo.EntityExtensions.Entity entity) =>
|
||||||
entity != null ? (entity.RelatedEntities != null ? (entity.RelatedEntities[0]) : null) : null;
|
entity != null ? (entity.RelatedEntities != null ? (entity.RelatedEntities[0]) : null) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -9,9 +9,9 @@ namespace EntityFrameworkCore.Projectables.Generated
|
|||||||
{
|
{
|
||||||
public static class Foo_EntityExtensions_GetFirstName
|
public static class Foo_EntityExtensions_GetFirstName
|
||||||
{
|
{
|
||||||
public static System.Linq.Expressions.Expression<System.Func<Entity, string>> Expression()
|
public static System.Linq.Expressions.Expression<System.Func<global::Foo.EntityExtensions.Entity, string>> Expression()
|
||||||
{
|
{
|
||||||
return (Entity entity) =>
|
return (global::Foo.EntityExtensions.Entity entity) =>
|
||||||
entity.FullName != null ? (entity.FullName.Substring(entity.FullName != null ? (entity.FullName.IndexOf(' ') ) : null?? 0)) : null;
|
entity.FullName != null ? (entity.FullName.Substring(entity.FullName != null ? (entity.FullName.IndexOf(' ') ) : null?? 0)) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -8,9 +8,9 @@ namespace EntityFrameworkCore.Projectables.Generated
|
|||||||
{
|
{
|
||||||
public static class Foo_C_Foo
|
public static class Foo_C_Foo
|
||||||
{
|
{
|
||||||
public static System.Linq.Expressions.Expression<System.Func<D, int>> Expression()
|
public static System.Linq.Expressions.Expression<System.Func<global::Foo.D, int>> Expression()
|
||||||
{
|
{
|
||||||
return (D d) =>
|
return (global::Foo.D d) =>
|
||||||
1;
|
1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -8,7 +8,7 @@ namespace EntityFrameworkCore.Projectables.Generated
|
|||||||
{
|
{
|
||||||
public static class Foo_C_Foo
|
public static class Foo_C_Foo
|
||||||
{
|
{
|
||||||
public static System.Linq.Expressions.Expression<System.Func<global::Foo.C, D>> Expression()
|
public static System.Linq.Expressions.Expression<System.Func<global::Foo.C, global::Foo.D>> Expression()
|
||||||
{
|
{
|
||||||
return (global::Foo.C @this) =>
|
return (global::Foo.C @this) =>
|
||||||
@this.Dees.First();
|
@this.Dees.First();
|
||||||
|
|||||||
+33
@@ -867,6 +867,39 @@ namespace Foo {
|
|||||||
return Verifier.Verify(result.GeneratedTrees[0].ToString());
|
return Verifier.Verify(result.GeneratedTrees[0].ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public Task DeclarationTypeNamesAreGettingFullyQualified()
|
||||||
|
{
|
||||||
|
var compilation = CreateCompilation(@"
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using EntityFrameworkCore.Projectables;
|
||||||
|
|
||||||
|
namespace Foo {
|
||||||
|
public static class EntityExtensions
|
||||||
|
{
|
||||||
|
public record Entity
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string? FullName { get; set; }
|
||||||
|
|
||||||
|
[Projectable]
|
||||||
|
public static Entity Something(Entity entity)
|
||||||
|
=> entity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
");
|
||||||
|
|
||||||
|
var result = RunGenerator(compilation);
|
||||||
|
|
||||||
|
Assert.Empty(result.Diagnostics);
|
||||||
|
Assert.Single(result.GeneratedTrees);
|
||||||
|
|
||||||
|
return Verifier.Verify(result.GeneratedTrees[0].ToString());
|
||||||
|
}
|
||||||
|
|
||||||
#region Helpers
|
#region Helpers
|
||||||
|
|
||||||
Compilation CreateCompilation(string source, bool expectedToCompile = true)
|
Compilation CreateCompilation(string source, bool expectedToCompile = true)
|
||||||
|
|||||||
Reference in New Issue
Block a user